When you face such questions, just look for an obvious relationship....The Tower snippet is a perfect example and a perfect explanation has been given by Thorn....Tower and Suscriber go hand in hand ...No tower, No signal which affects the Subscriber which shows how dependent Suscriber is on Tower and Without a subscriber what sense can the installation of a tower make ?
I think there are a couple of concepts that can get a little confused: Coupling and composition. We could assume that each Tower object could have at least a Subscriber object (composition) since we are providing a Subscriber object in a Tower constructor. But just because you have composition it doesn't mean you need to have coupling. As long as you rely on a well-defined API when using the instances of other classes that you have, you still have loose coupling.
Then, why could answer 1 be thought of as coupling?
Let's assume that Subscriber doesn't have any explicit constructors. In this case the code will work, because there is a default no-args constructor provided by the compiler. But the moment the Subscriber class changes by getting an explicit constructor taking at least one argument, that will break this code (since Subscriber will stop having a no-args constructor.)
It really depends on whether the class Subscriber publishes a no-arg constructor as part of its API.
But even if the no-arg constructor is not part of Subscriber's API, there is yet another obstacle to consider this true coupling between Tower and Subscriber:
Is not necessarily part of Tower's code. This could be in some other class that just happens to be constructing a new Tower object.
The Tower code being used would be:
How can you argue now that there is tight coupling between Tower and Subscriber here? There is a dependency in the sense that Tower is relying on Subscriber being accessible in the class path for this to be able to compile, but is that really coupling? There are no specifications as to how we are getting the Subscriber object. That responsibility falls on the code that calls this Tower constructor.
You could do something different:
Tower t = new Tower(Subscriber.getNewSubscriber());
In this case, you use a static factory method (which is clearly part of Subscriber's API) to get a new instance of Subscriber. It is much harder to argue that this could be tight coupling, because you are using an explicitly coded factory method which forms part of the Subscriber class' API.
All code in my posts, unless a source is explicitly mentioned, is my own.
Here you should watch two things:
1st) is that one case here is obviously more fragile than other cases. Line 1 depends on some other class. All other cases are primitives, primitive wrappers or String literal(which is class instance, but in this context is more closer to primitives than full-fledged class).
2nd) names of classes in Line 1. They are not obviously connected in some natural way. Subscriber is not part of Tower. Think about it. Subscriber is not needed to make Tower. Other cases are passing some parameters that might actually be important for Tower construction. Like: String literal "413-08" could be register number of Tower, name of Tower. In case where Subscriber is passed it just does not make sense. How the heck is Subscriber needed for construction of Tower???
What do you think where is coupling tighter in this two examples:
1. Car car = new Car(new Engine());
2. House house = new House(new Dog());
Think about difference between this two.
Car is not a car without Engine, but House is House without Dog, although it can have a Dog inside.
Hope this helps a bit ;)
You make good points. I am just going by what the SCJP 6 exam considers coupling. According to K&B page 152: Coupling is "the degree to which one class knows about another class. If the only knowledge class A has about class B is what class B has exposed through its interface, then class A and class B are loosely coupled."
In this case the part of B's interface that A cares about is the no-arg constructor. As long as B continues to have a no-arg constructor, this code will work. So there is no tight coupling in this case. And as I said in my other post, line 1 is not necessarily part of A's code, so even if we could conclude (which is stretching things a little) that the no-arg constructor is not part of B's interface, that is not enough to conclude anything about A being tightly coupled with B.
Note that K&B mention also that what the exam considers coupling is a little subjective, so I'm not saying that you are wrong.
For the purpose of the exam, though, I don't see any tight coupling in this example. You can argue that it's not a good design to have a Tower constructor that takes a Subscriber object (the same way that it's not a good design to have a House constructor that takes a Dog. It is a bad design, but not coupling by the SCJP definition of coupling (according to K&B.)
I believe Line 1 to be the best example of tight coupling. Here the constructor for the Tower class is taking, a Subscriber Object as an argument. In my mind this suggests that there is a strong reliance between a Tower and a Sunscriber. As the rules go, one should seek to achive high cohesion and Loose coupling, that is to say a Class should know and control as much about itself as poosible with as little opportunity as possible for designated control to another class. In this case the Tower Constructor is reliying heavily upon another class for its construction, and as such is tightly coupled to the Subscriber Class.
be a well encapsulated person, don't expose your privates, unless you public void getWife()!
Joined: Dec 16, 2008
I disagree. Just because you provide an instance of a class as an argument to a constructor of other class it doesn't mean that you have tight coupling. You have dependency, but dependency is not the same as coupling. Coupling is dependency on a class' implementation code, but as long as your dependency sticks to the public interface you have no tight coupling (according to what the SCJP exam considers coupling.)
If what you said were true, then all forms of dependency would entail tight coupling.
Also, according to the definition of coupling for the SCJP exam, I fail to see any case where you can have tight coupling without poor encapsulation.
Joined: Jul 23, 2008
True. However, one other thing that helps to discover coupling, is the implementation of the class i.e the methods. Since we cannot see them here, it is then hard to decide on the coupling. However if we look at Camerons example
here, the anaolgy is that the car class is able to access and alter the behaviour in the Driver class. In this instance it is the existence of an object with invokable methods on another object. So looking at our present example, the new Subscriber means in effect that the new Subscriber object has the potential to affect the Tower Object.
I am not suggesting, that Dependency is tight coupling but as we are forced to choose one of the options given in the question, I would have chosen the first one for the reason above. Yet, as I stated before it is hard to tell without seeing the implementation of the class itself.