Anyone point out me some good example for cohesion and coupling. Increasing cohesion/coupling will lead to good software design?
It's a bit more complex than that. :-)
High cohesion within modules and low coupling between modules are often regarded as related to high quality in OO programming languages.
For example, the code inside each Java class must have high internal cohesion, but be as loosely coupled as possible to the code in other Java classes.
Chapter 3 of Meyer's Object-Oriented Software Construction (2nd edition) is a great description of these issues.
Let's give an extreme example of tight coupling to get the picture: you've developed a tic tac toe game and everything is been put inside the main()
method. There are no other classes or methods. The code in the main()
method is in no way reuseable and has probably lot of repeated code. This is a bad design. Splitting and refactoring the tasks/responsibilities over classes/methods will improve cohesion and coupling.
To add on what CesarGon has mentioned,
Cohesion refers to what the class (or module) will do. Low cohesion would mean that the class does a great variety of actions and is not focused on what it should do. High cohesion would then mean that the class is focused on what it should be doing, i.e. only methods relating to the intention of the class.
Example of Low Cohesion:
-------------------
| Staff |
-------------------
| checkEmail() |
| sendEmail() |
| emailValidate() |
| PrintLetter() |
-------------------
Example of High Cohesion:
----------------------------
| Staff |
----------------------------
| -salary |
| -emailAddr |
----------------------------
| setSalary(newSalary) |
| getSalary() |
| setEmailAddr(newEmail) |
| getEmailAddr() |
----------------------------
As for coupling, it refers to how related are two classes / modules and how dependent they are on each other. Being low coupling would mean that changing something major in one class should not affect the other. High coupling would make your code difficult to make changes as well as to maintain it, as classes are coupled closely together, making a change could mean an entire system revamp.
All good software design will go for high cohesion and low coupling.
Increased cohesion and decreased coupling do lead to good software design.
Cohesion partitions your functionality so that it is concise and closest to the data relevant to it, whilst decoupling ensures that the functional implementation is isolated from the rest of the system.
Decoupling allows you to change the implementation without affecting other parts of your software.
Cohesion ensures that the implementation more specific to functionality and at the same time easier to maintain.
The most effective method of decreasing coupling and increasing cohesion is design by interface.
That is major functional objects should only 'know' each other through the interface(s) that they implement. The implementation of an interface introduces cohesion as a natural consequence.
Whilst not realistic in some senarios it should be a design goal to work by.
Example (very sketchy):
public interface IStackoverFlowQuestion
void SetAnswered(IUserProfile user);
void VoteUp(IUserProfile user);
void VoteDown(IUserProfile user);
}
public class NormalQuestion implements IStackoverflowQuestion {
protected Integer vote_ = new Integer(0);
protected IUserProfile user_ = null;
protected IUserProfile answered_ = null;
public void VoteUp(IUserProfile user) {
vote_++;
// code to ... add to user profile
}
public void VoteDown(IUserProfile user) {
decrement and update profile
}
public SetAnswered(IUserProfile answer) {
answered_ = answer
// update u
}
}
public class CommunityWikiQuestion implements IStackoverflowQuestion {
public void VoteUp(IUserProfile user) { // do not update profile }
public void VoteDown(IUserProfile user) { // do not update profile }
public void SetAnswered(IUserProfile user) { // do not update profile }
}
Some where else in your codebase you could have a module that processes questions regardless of what they are:
public class OtherModuleProcessor {
public void Process(List<IStackoverflowQuestion> questions) {
... process each question.
}
}
I would like to point out to this article: S.O.L.I.D. Software Development, One Step at a Time.
Grz, Kris.
Structured Design by Yourdon and Constantine is a good discussion of this point, although the examples in the book show its age.