Friday, May 25, 2012

Principles of Object Oriented Design

The first and the foremost key factor in software development is the requirements change.And this brings a greatest challenge for software developers to have a design that is open for adopting requirement changes or new requirements getting added altogether. You might have heard about design debt quadrant, right?
The second key factor is that over a period of time, design degrades. In other words, design debt increases.

Characteristics of a good design are robust, extensible, maintainable etc and how about the characteristics of a bad design? They are rigidity(Making a change in the software is difficult), fragility (tendency of software to break in several places by a single change), immobility(unable to rescue), viscosity (Easy to do the wrong thing but hard to do the right thing resulting in tendencies of the developers to avoid 'clean fix')

What causes design degradation? The changes that introduce new and unplanned dependencies, we have dependency firewalls. 

Well, we saw what are design challenges today in any software development activities. These challenges can be beaten by applying or following certain design principles(object oriented) which I am going to talk about in this post. First I will explain about class design principles and move on to package design principles which are fair enough to understand.

Principles of Class Design

1. Single Responsibility Principle: This principle says that a class has to change for one reason and should never be more than one reason. For example a Rectangle class which draws the rectangle as well as calculates its area is not following SRP. To resolve this, we need to have two rectangle classes one for drawing the rectangle and another for calculating the area. Context of responsibility is defined as "A reason for change".

2. Open Close Principle: This principle says that a method/class should be "Open for extension but closed for modification". New functionality will be implemented  by a new class or a new method.Make all the member variables private. Minimize the use of getter and setter methods. The key for OPC is abstraction. Add new code for new functionality, don't modify the existing code. Concrete implementation of the interfaces somewhere(open for extension), but existing code must be closed for new functionality.
For a detailed example for OPC, have a look at this link

3. Liskov Substitution Principle: This principle says that in class hierarchies, subclasses should be substitutable for base classes.The answer for the question, "Is square a rectangle?" is that it depends on the interface. Interface define the behavior, they also define assumptions constraints. Square can be a rectangle or not rectangle based on how we design the interface. See an example for this

4. Dependency Inversion Principle: This principle says that the key is to depend upon the abstractions, abstraction interfaces do not change and concrete classes can be replaced. Avoid deriving from the concrete classes, associating to or aggregating concrete classes. See an example for this.

5. Interface Segregation Principle: This principle says that clients should not be forced to depend upon interfaces. Do not depend on concretions. When a class collects interfaces for various purposes, its called a fat interface. Click here to see an example for this.

Principles of Package Design
A package is a group of classes and following are certain principles to consider while designing them
 
1. Acyclic Dependency Principle: It says that dependencies between packages must NOT form cycles. The key here is to break the cycle of dependencies, break cycles with abstract interfaces, splitting packages, reorganizing packages and then reducing coupling. The basic rule that I follow is to visualize high level dependencies and then rationalize them separating the interfaces and implementations to break dependencies that I don't want.

2. Stable Dependency Principle: This principle says that the dependencies between packages in a design should be in the direction of the stability of the packages. To be more precise, a package should only depend upon packages that are more stable than itself. So the question is how to measure the stability of the packages? There is an algorithm that says to calculate something called Afferent coupling (Ca). For detailed information on package stability measurement, look at this under measuring stability section. There are tools to do this, for example JDepend for Java.

Well, the rationale behind these principles is that the design cannot remain static.we design some packages with some expectations that these packages will undergo changes.
 

No comments:

Post a Comment

Related Posts Plugin for WordPress, Blogger...