|< Free Open Study >|
4.4 Heuristics for the Uses Relationship
The typical relationship among the main, top-level objects in an application is the uses relationship. In an optimal object-oriented design, none of these uses relationships can be refined into containment. A main problem to watch for is uses relationships that should have been refined into containment but were not. There is a heuristic that can help identify these.
This heuristic claims that the list of classes another class uses should be kept to a minimum. In the worst case, an object-oriented design will consist of a collection of primitive, simplistic classes, all of which use each other. The top-level design will be very difficult to comprehend. Notice that our heuristic of avoiding a god class is not violated here. We may have distributed system intelligence very uniformly among the large group of top-level objects. The solution is to look for places in the uses relationship graph where one class communicates with another group of classes and ask, "Can I replace this group of classes with one class containing the group, thereby reducing the number of collaborations?" There will be many such tests of which only a percentage will answer yes. These should be wrapped in containing classes to reduce complexity. For example, consider the restaurant patron and types of food shown in Figure 4.8. A better solution is to wrap the food in the containing class "meal" in order to reduce the number of collaborations at the top level of the design.
One can argue that we have actually increased the number of uses relationships from three to four, but thanks to data hiding we do not count uses relationships inside the meal class. They are invisible to the restaurant patron and are simply implementation details of the meal. We will see later in this chapter that containment is the simplifying relationship of the object-oriented paradigm. Whenever we can contain one item in another, it implies that we can ignore the contained object at some high level of design.
It is important to note that once an object of a class sends a message to an object of another class, a collaboration exists between the two classes. Some developers have tried to quantify the collaboration minimization heuristic to state that a class should not collaborate with more than six classes. These developers are trying to build complexity metrics based on short-term memory restrictions. While this information is applicable to containment and inheritance relationships, I am not convinced that the short-term memory constraint applies in this case. In order to understand a single requirement (e.g., scenario, use case) in an application, one does not have to conceptualize all of the collaborations of a class. Since understanding a class is usually accomplished by analyzing its roles in an application's requirements, developers rarely analyze all of the collaborations outside the scope of a single requirement.
|< Free Open Study >|