Coupling and Cohesion
Coupling and Cohesion
Cohesion and coupling are concepts that are reasonably easy to understand, but nonetheless, it is worthwhile to gather readable illustrations of where they apply. Browse the hundreds of Web pages that attempt to explain these concepts, picking your favorite examples. Categorize these examples, so that the reader will see the big picture, rather than just a set of redundant illustrations. Many of these pages mention related concepts; list some of them and explain how they relate to cohesion and coupling.
Introduction
Cohesion and Coupling are two cornerstones of Object-Oriented Programming. They sound similar, but have very different meanings. Cohesion is the act or state of sticking together or the logical agreement". It is the basic idea that a class has a focused set of responsibilities or behaviors from a particular perspective. In contrast to cohesion, Coupling refers to the physical connections between elements of the OO design (eg: the number of collaborations between classes or the number of messages passed between objects) within an OO system. In a simple way, it gives the measure of the interdependence of one module to another.
Cohesion
Cohesion is the "glue" that holds a module together. It can be thought of as the type of association among the component elements of a module. Cohesion is related to the Single Responsibility Principle. Generally, one wants the highest level of cohesion possible. An object with high cohesion is defined for one purpose and it performs only that purpose. An object with low cohesion tends to try to do a lot of different things. For example, if there is a Card object which is responsible for drawing itself, sending messages back to the server, and also executing game logic then it has low cohesion because that one class is attempting to do too much. A system can also have low cohesion if too many objects are attempting to do the same thing. For example, if a system has objects to implement a NetRunner game and every card has a unique class with a rendering method and that method is nearly identical in all classes, then the system has low cohesion. A good software design is always designed to achieve high cohesion.
Coupling
Coupling is a qualitative measure of the degree to which the classes, modules or subsystems are connected to one another. It can be defined as the amount of interaction of one object with another object, or one module with another module. For a good software design, it is always advisable to minimize coupling. Low coupling does not mean no coupling, the goal is reduction rather than elimination of coupling. A system with no coupling is, by definition, not a system. Low coupling indicates that each object or module performs independent tasks. In general, low coupling can be well explained by Law of demeter. It states that classes within a module or subsystem should have only limited knowledge of classes in other modules or subsystems. In simple terms, 'Law of Demeter' says "Each unit should only talk to its friends; don't talk to strangers". Strong coupling means that one object or module is dependent on other object or module to perform an operation or task. It simply means that the object or module is strongly coupled with the implementation details of another object or module. With low coupling, a change in one module will not require a change in the implementation of another module.
Number of messages passed between objects can be reduced. Messages can be simplified using few parameters. Avoid requiring multi-message sequences.
Reduce extent to which objects depend on the internal structure of each other. Reduce the use of superclasses instance variables by subclasses (strong form of the Law of Demeter).
3. Strive for moderate inheritance coupling. It can be achieved in the following ways -
Abstract so that subclasses depend on the methods (but not the structure!) of their superclasses. Use or refine as many of superclass' operations as possible in the child classes.
It can be simply understood as, breaking something complex into set of manageable pieces. Consider the example of order processing system. If we decide to write entire software in only one program, it will become lengthy, unmanageable, complicated and hard to debug. Instead, we can divide it into modules or subsystems like order entry, order processing, billing and complaints. [edit]
Conclusion
Code that is easy to maintain and reusable can be attained by sticking to loose coupling and high cohesion in objects. The concept of coupling is usually related to the concept of cohesion so low coupling facilitates high cohesion, and vice versa. It is difficult to obtain perfect high cohesion and low coupling throughout the program. Once all the unitary functions that depend only on their inputs are written, a bit of less cohesive and more coupled code is required to glue them together into a working program. But, there are also times where tight coupling is desirable. Tighter the coupling, it improves performance as it reduces the cost of interfaces. So, tight coupling is important when one process is very stable and wants maximum performance and loose coupling comes into play when flexibility is required rather than stability. There can also be situations where even though high cohesion is attained, tight coupling is also present. This means though it may be logically laid out, it's tough to change because of tight interdependencies which is pretty bad. The other kind of bad software is eventhough the module is loosely coupled but it may lack cohesion. That means that there are few explicit interdependencies between modules, but none of the modules are necessarily authoritative about any particular aspect of the system. This in turn results in a scattergun approach to ongoing system evolution as even minor changes ripple through multiple components or systems. As to conclude, the objective of a good software should be to achieve high cohesion and low coupling.