passing the main object is allowing the quacker method in Duck class to change the variable values
Improving coupling means we should reduce the class to class interaction
this is required because of following reasons
Suppose some programmer has written Duck class and another has written the Main class
now the programmer of the Main class wants to write something very very important to the class and does not want it to give it to another classes
but wait here
we are passing the object of the main class to the Duck class quacker method which can modify the Main class which is not desired at all
so we should not pass the Main type parameter to the quacker method
I hope this helps a little
no need to make it private because we are not accessing it from some other class (in our case, the main class)
SCJP 6 [86%], OCPWCD [84%], OCEJPAD [83%]
If you find any post useful, click the "plus one" sign on the right
Just a little "point of view" ( I had a hard time with the idea of coupling early on...)
changing the variable from default to private is more about encapsulation than coupling because another class in the same package can have direct access to the variable and THAT is, as I say, an encapsulation problem!
The way you might want to think about the second issue: the quacker() method in class Duck has the following signature:
so you can't ever pass it anything BUT a Main. This is a) inflexible and b) it makes Duck class highly dependent on the existence of the Main class.
Now, how do you decrease that coupling? That is where the magic of the "interface" comes in to play.
What if you created and interface called "Avian" and, in that interface you specified the signatures of some behaviors (like flaps, flies, chirps.... things that all avians do) and then made Duck implement Avian. But, at the same time, you could make a Sparrow that implements Avian, an Ostrich, a seagull, a parakeet..... whatever you want.
Now, alter quacker to the following signature:
Now, quacker no longer has to have a "concrete class" Main object.... it can accept any implementer of Avian. This makes quacker() dependent on the interface type NOT the concrete type Main. That makes the code much more flexible.
I realize that this might be a little confusing because your example class IS Duck and so you might think that...."why would I want anything BUT a duck?" But try to separate this specific example from the issue of coupling that we are discussing.
If I had a method that was designed to implement a logging class called PrintLogger. Let's say that I have another class LogSetup that has a method that is designed to set a log class and it has a signature like this:
The only thing that you can ever pass to setLogger() is a PrintLogger.
Let's change that a little...
Let's design an interface called Loggable. It might have method signatures like logFine(), logInfo(), logFatal()...just to make an example.
Then we change PrintLogger class to implement Loggable
now, you can change LogSetup to look like this:
now, you can implement a FileLogger, a NetworkLogger, a TapeDriveLogger, a ScreenLogger that all implement the Loggable
interface and you can pass any of them to the setLogger method, not JUST the PrintLogger.
This is much more flexible design and you can, if you care to add and remove logger types without breaking the LogSetup code.
So, cutting it down to the essentials, any time you specify the use of a concrete class and pass concrete classes around it increases coupling.
When you design interface types, then design concrete classes that implement the interfaces, then have your code specify and pass by interface
type rather than concrete type, this reduces coupling.
I hope that this will give you some help in understanding.
SCJP - 86% - June 11, 2009