< Day Day Up > |
Highly cohesive, loosely coupled classes are a common goal for class design. A cohesive class encapsulates a single concept or idea. A loosely coupled class does not depend on the implementation of other classes. [*]
6.1.1. CohesionEach class should represent one abstraction. Each class should have a one-line description of the class's purpose and meaning. If you cannot describe a class briefly , it probably represents more than one abstraction. Responsibilities that are added to a class should fit within the description. The CDDisc class just does not feel right. It appears that the class is mixing two concepts. Looking back through the requirements and use cases, we discover the term Rental . That term seems to be a missing abstraction. Note that a class can represent an event as well as a physical object. The one-line description of a Rental is:
Tim and I alter CDDisc so that it has a current Rental if it is rented. Now the class looks like this: class CDDisc CDRelease cd_release PhysicalID physical_id Rental current_rental rent(Customer a_customer) return_a_rental( ) class Rental Customer renter Timestamp start_time Timestamp end_time
6.1.2. CouplingCoupling measures how two classes interrelate. If two classes are coupled, a change in one class can force a change in the other class. There are three degrees of coupling : tight , common , and loose . Tight coupling means that a change in the implementation of one class forces a change in the implementation of the other. With common coupling, the second class uses the interface methods of the first class. If the implementation of the first class changes, the second class does not need to change. Loose coupling means that a class does not even rely on the interface of another class, only on its existence. For most classes, you should aim for common or loose coupling. Common coupling follows a maxim stated in the book Design Patterns : "Design to an interface, not an implementation." Callers should rely only on the methods declared in the class interface and not on the implementation of those methods. For example, the users of the CDDiscCollection class access it through the following interface: interface CDDiscCollection CDDisc find_by_physical_id(PhysicalID a_physical_id) CDDisc [] find_by_cd_release(CDRelease a_cd_release) // Standard collection operations: add(CDDisc a_cd_disc) remove (CDDisc a_cd_disc) The underlying implementation is transparent to the users. When a programmer calls the methods of this class, the programmer does not need to know about nor address anything about how they are implemented. No matter how radically the implementation might be changed in the future, as long as the methods continue to function properly, any code that calls them does not have to be changed.
|
< Day Day Up > |