Logout

Home OOP Option Last Next

D.1.7

Outline the need to reduce dependencies between objects in a given problem.

 

Teaching Note:

Students should understand that dependencies increase maintenance overheads.

 

Sample Questions:

----

Q1. Outline a negative effect that a future change in the design of the Sales object
might have on this suite of programs.

-----

Q2. Outline the reasons for keeping dependencies to a minimum. You should include
an example using the classes described so far.

----

sdfsdfsf

JSR Notes:

What we mean by Dependencies

First of all, by "dependencies" we are talking about when there are any "connections", i.e. relationships between classes. So looking at a UML class diagram, every time there is an arrow, either for a "is a", "has a", or "uses" relationship, we would see this is a dependency situation.

(So do note that this is not just talking about the "uses" relationships, which are also refered to, specifically, as "dependency" - rather it is all connections between classes.)


Limiting Dependencies

On one level, limiting dependencies seems to be counter to the fundamental pillar of OOP programming, decomposition, i.e. dividing a big problem up into smaller problems via classes. But the thing is, decomposition, by definition, creates dependencies between objects, and dependencies can very well lead to problems.

Potential Problems of Decompostion (i.e. possible problems when there are too many dependencies)

Messines

- Too much decomposition potentially makes the program harder to follow, and more messy, with there being so many classes*

More Potential Boken Connections

- There are more interactions/communications between classes that could potentially be broken**

Maintenance Overhead

- There is more maintenance overhead, given that changes to one class demand changes to other classes***


Still, remember that there are many advantages to decomposition.

Advantages of Decomposition, (in spite of dependencies) including

General advantages:

A. Divide and Conquor approach
B. Abstraction: focusing in on individual problems, ignoring other details

Leading to, specifically:

1. Faster development
2. Easier debugging
3. Easier updating in the future
4. Re-usability

So you should look for a happy medium between decomposition, but not too much decomposition - i.e. limiting dependencies. Yes, we want to divide a big problem up into smaller pices, but we don't want to over-do it. We do indeed need to be conscious that too many dependencies can become problematic.

 

In Summary, Back to the Assessment Statement:
"Outline the need to reduce dependencies between objects in a given problem."

Changes in one class in a dependency may affect other dependent classes. And this may cause programs using the dependent class to not function correctly.

Less dependencies lead to reduced maintenance overhead, since a programmer editing a particular class would not have to be concerned so much with other classes; it allows the programmer to focus more on the class they are writing.


 

 

More on the Problems of Dependencies

More on "Messiness"*

You can imagine that if you went wild with classes, making separate classes for every little thing, it would soon be a mess, and would be hard to keep track of what does what where. You may end up with classes dependent on classes, which are dependent on other classes, and so on. This would be hard to keep track of. Furthermore if/when another programmer comes to work on your program many years later, after you're long gone, it will be all the harder for them to makes sense of all your classes and dependencies.

More on More Potential Broken Connections**

One other reason to keep dependencies to a reasonable number is if the "connection" between them gets broken, it can screw up the whole program. And keeping the connections working correctly takes extra attention since you are working with different classes, not within the same class/code. An easy example to appreciate this is when you change the constructor of one class, you need to change all of the instances of calling that constructor in other classes which use it. This is one example of the "maintenance overhead" mentioned in the Teaching Note.

More on Maintainence Overhead***

Breaking a program up into different independent parts is great for focus, and the isolation, which makes for easier development, testing and debugging. The problem is that classes in a project are not every truly independent. The whole idea is that classes are used one way or the other by other classes; that's what they are there for. So depending on the complexity of your interactions, there will always be at least one other class which inteacts with a class you are working on. And any change you make may very well affect that another class, which may then have to be changed itself, to reflect the change you are making to the class you are working on. And where there is a web of interconnections, individual changes to any given one class can ripple through other classes, adding still more to the maintenance overhead.

 

 

 

"Refactor" to the Rescue

In terms of potential broken connections and the maintenance overhead, IntelliJ and other modern IDEs can "refactor" other classes when necessary. Refactoring is basically making the necessary changes to other classes (or indeed in the same class, like with changed variable names) when a dependency requires it based on a certain change to a certain class in the project. This makes life a lot easier, but still, as a general rule, you want to limit the amount of refactoring that is necessary in the first place, with a balance between decomposition and limiting dependencies.