97
Designing with Maintainability in Mind
Highly Coupled Classes
Classes that are highly dependent on one another are considered highly coupled. Thus, if a
change made to one class forces a change to another class, these two classes are consid-
ered highly coupled. Classes that have no such dependencies have a very low degree of cou-
pling. For more information on this topic, refer to The Object Primer by Scott Ambler.
If the classes are designed properly in the first place, any changes to the system should only
be made to the implementation of an object. Changes to the public interface should be
avoided at all costs.Any changes to the public interface will cause ripple effects through-
out all the systems that use the interface.
For example, if a change were made to the getName() method of the Cabbie class,
every single place in all systems that use this interface must be changed and recompiled.
Simply finding all these method calls is a daunting task.
To promote a high level of maintainability, keep the coupling level of your classes as
low as possible.
Using Iteration
As in most design and programming functions, using an iterative process is recommended.
This dovetails well into the concept of providing minimal interfaces.A good testing plan
quickly uncovers any areas where insufficient interfaces are provided. In this way, the
process can iterate until the class has the appropriate interfaces.This testing process is not
simply confined to coding.Testing the design with walkthroughs and other design review
techniques is very helpful.Testers’ lives are more pleasant when iterative processes are used,
because they are involved in the process early and are not simply handed a system that is
thrown over the wall at the end of the development process.
Testing the Interface
The minimal implementations of the interface are often called stubs. (Gilbert and McCarty
have a good discussion on stubs in Object-Oriented Design in Java.) By using stubs, you can
test the interfaces without writing any real code. In the following example, rather than
connect to an actual database, stubs are used to verify that the interfaces are working prop-
erly (from the user’s perspective—remember that interfaces are meant for the user).Thus,
the implementation is really not necessary at this point. In fact, it might cost valuable time
and energy to complete the implementation at this point because the design of the inter-
face will affect the implementation, and the interface is not yet complete.
In Figure 5.8, note that when a user class sends a message to the
DataBaseReader class,
the information returned to the user class is provided by code stubs and not by the actual
database. (In fact, the database most likely does not exist yet.) When the interface is com-
plete and the implementation is under development, the database can then be connected
and the stubs disconnected.