pointer-image   30   Write Cohesive Code

 

“You are about to write some new code, and the first decision you need to make is where to put it. It doesn’t really matter where it goes, so just go ahead and add it to the class that happens to be open in your IDE now. It’s easier to keep track of code when it’s all in one big class or component anyway.”

images/devil.png

Cohesion is a measure of how functionally related the members of a component (package, module, or assembly) are. A higher value of cohesion indicates that the members work toward one feature or set of features. A lower value of cohesion indicates that the members provide a disparate set of features.

Imagine tossing all your clothes into one drawer. When you need to find a pair of socks, you will have to wade through all the clothes you have in there—your pants, underwear, T-shirts, etc.—before you can find the pair of socks you want. It can be very frustrating, especially when you are in a hurry. Now, imagine keeping all your socks in one drawer (in matching pairs), all your T-shirts in another, and so on. The effort to find a pair of socks is merely to open the right drawer.

Similarly, how you organize a component can make a big difference in your productivity and overall code maintenance. When you decide to create a class, ask yourself whether the functionality provided by this class is similar to and closely related to the functionality of other classes already in that component. This is cohesion at the component level.

Classes are also subject to cohesion. A class is cohesive if its methods and properties work together to implement one feature (or a closely related set of functionality).

Consider Mr. Charles Hess’s 1866 patent of a “Convertible Piano, Couch, and Bureau” (Figure 4, U.S. Patent 56,413: Convertible Piano, Couch, and Bureau). According to his patent claim, it features the “…addition of couch, bureau…to fill up the unused space underneath the piano….” He goes on to justify the need for his convertible piano. You may have seen your share of classes that resemble this invention in your projects. There isn’t much cohesion here, and one can imagine that the maintenance on this beast (changing the sheets, tuning the piano, etc.) is probably pretty difficult.

images/patent56413.png

Figure 4. U.S. Patent 56,413: Convertible Piano, Couch, and Bureau

For an example from this century, Venkat came across a twenty-page web application written using ASP. Each page started out with HTML and contained a serious amount of VBScript with embedded SQL statements to access a database. The client was rightfully concerned that this application had gotten out of hand and was hard to maintain. If each page contains presentation logic, business logic, and code for data access, too much is going on in one place.

Suppose you decide to make a slight change to the database table schema. This small change will result in a change to all the pages in this application and also multiple changes in each page—this application becomes a disaster quickly.

If instead the application had used a middle-tier object (such as a COM component) to access the database, the impact of change in the database schema would have been localized, making the code easier to maintain.

The consequences of having low cohesion are pretty severe. Suppose you have a class that implements five disparate features. This class will have to change if the requirements or details of any of these five features change. If a class (or a component) changes too frequently, such a change may ripple through the system and will result in higher maintenance and cost. Consider another class that implements just one feature. This second class will change less frequently. Similarly, a component that is more cohesive has fewer reasons to be modified and is thus more stable. According to the Single Responsibility Principle (see Agile Software Development, Principles, Patterns, and Practices [Mar02]), a module should have only one reason to change.

A number of design techniques can help. For instance, we often use the Model-View-Controller (MVC) pattern to separate the presentation logic, the control, and the model. This pattern is effective because it allows you to achieve higher cohesion—the classes in the model contain one kind of functionality, those in the control contain another kind, and those in the view are solely concerned with UI.

Cohesion affects reusability of a component as well. The granularity of a component is an important design consideration. According to the Reuse Release Equivalency principle (Agile Software Development, Principles, Patterns, and Practices [Mar02]), “Granularity of reuse is the same as the granularity of release.” That is, a user of your library should have a need for the entire library and not only a part of it. Fail to follow this principle, and users of your component are forced to use only part of the component you have released. Unfortunately, they’ll still be affected by updates to the parts they don’t care about. The bigger the package, the less reusable it is.

images/angel.png

Keep classes focused and components small.

Avoid the temptation to build large classes or components or miscellaneous catchall classes.

What It Feels Like

Classes and components feel tightly focused: each does one thing, and does it well. Bugs are easy to track down, and code is easy to modify because responsibilities are clear.

Keeping Your Balance

  • It’s possible to break something down into so many little parts that it isn’t useful anymore. A box of cotton fibers isn’t helpful when you need a sock.[31]

  • Cohesive code can be changed proportionally to the change in requirements. Consider how many code changes you need to implement a simple functional change.[32]

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.137.127