The Principles of Object-Oriented Design

At this moment, a lot of source code are been writing by thousands and thousands of programmers all around the world. Most of them uses an object-oriented language, but probably just a few have knowledge of the ODD, which I consider crucial for a reusable and extensible project.

What are The Principles of Object-Oriented Design

In March of 1995 UncleBob wrote an article that was the first glimmer of a set of principles for OOD. These principles expose the dependency management aspects of OOD. When dependencies are well managed, the code remains flexible, robust, and reusable. So dependency management, and therefore these principles, are at the foudation of the -ilities that software developers desire.

The first principles are about class design, which are:

  • The Single Responsability Principle (SRP): a class should have one, and only one, reason to change.
  • The Open-Closed Principle (OCP): software entities should be open for extension, but closed for modification.
  • The Liskov Substitution Principle (LSP): subtypes must be substitutable for their base types.
  • The Dependency-Inversion Principle (DIP): depend on abstractions, not on concretions.
  • The Interface-Segregation Principle (ISP): make fine grained interfaces that are client specific.

The Single Responsability Principle

In the context of the SRP, responsability is defined as a reason to change. Therefore, when the requirements change, that change will reflect in all classes that assume that responsability. If a class assumes more than one responsability,  then there will be more than one reason for it to change. In addition, this responsabilities becomes coupled and software is all about low coupling and high cohesion.

A good design is to separate two responsabilities in two completely different classes.

The Open-Closed Principle

This principle is about Rigidity, which is the tendency for a software to be difficult to change, even in simple ways. A design is rigid if a single change causes a cascade of subsequent changes in dependent modules. The more modules that must be changed, the more rigid the design.

The OCP advises us to refactor the system so that further changes will not cause more modifications. If OCP is well applied, then changes are achieved by adding new code, not by changing old code that already exists.

Modules that conform to the Open-Closed Principle have two primary attributes:

  • Open for extension: this means that the behavior of the module can be extended. As the requirements of the application change, we are able to extend the module with new behaviors that satisfy those changes.
  • Closed for modifications: extending the behavior of a module does not result in changes to the source or binary code of the module. The binary exacutable version of the module remais untouched.

How to be conform with this principle? Abstraction. This topic is covered by ICP.

The Liskov Substitution Principle

The LSP is one of the prime enablers of the OCP. It is the substitutability of subtypes that allows a module, expressed in terms of a base type, to be extensible without modification.

This principle is about inherintance and polymorphism. It exposes that base and concrete classes must be substitutable in all aspects and behaviors. Let’s take the Square and Rectangle example. In math, a Square is a Rectangle and this is the reason why many programmer design a Square as a derivate of a Rectangle. However, this is a really poor design. Look at the code below, assuming that a Square class extends a Rectangle class.


void f (Rectangle r) {
     r.setWidth(5);
     r.setHeight(4);
     assert(r.getArea() == 20);
}

The f functions is able to accept Rectangles and Squares object. With that in mind, the first problem is a Square does not have, in its concept, the attributes width and height. But, this should be acceptable. The second problem is  the need of overriding the setWidth and setHeight methods of Square object to maintains the object integrity. The final, and the real problem is that this function works just for Rectangle and not for Square. Since, for these function, Square is not substitutable for Rectangle, which violates the LSP.

The LSP makes it clear that in ODD, the IS-A relationship pertains to behavior that can be reasonably assumed and that clients depend on.

The Dependency-Inversion Principle

  1. High-level modules should not depend on low-level modules. Both should depend on abstractions.
  2. Abstractions should not depend on details. Details should depend on abstractions.

More traditional software developers methods, such as Structured Analysis and Design, tend to create software structures in which high-level modules depend on low-level modules, and in which policy depends on detail. The dependency structure of a well-designed, object-oriented program is inverted with respect to the dependency structure that normally result from traditional procedural methods.

However, considering the implications of a high-level module that depend on a low-level module you will see that changes to the lower level modules can have direct effects on the higher level modules and can force them to change in turn. This is not a good idea at all.

The modules that contain high-level business rules should take precedence over, and be independent of, the modules that contain the implementation details. High-level modules simply should not depend on low-level modules in any way. In contrast, they should depend on abstractions. In that way, you are able to change concrete implementations with no changes to its clients.

The Interface-Segregation Principle

This principle deals with the disavantages of fat interfaces. Classes that have fat interfaces are classes whose interface are not cohesive. In other words, the interfaces of the class can be broken up into groups of methods, each one serving a different set of clients. So, some clients use one groups of member functions, and others clients use the other groups.

The ISP acknowledges that there are objects that require noncohesive interfaces. however, it suggests that clients should not know about them as a single class. Instead, client should know about abstract base classes that have cohesive interfaces.

Conclusion and References

This is just the beginning of Object-Oriented Design. Remeber to not apply those principles and patterns to a big, up-front design. Rather, they are applied from interation to interation in an attempt to keep the code ,and the design it embodies clean.

You can read more about OOD principles here or in the book Agile Software Development, Principles, Patterns and Practices, in which this post is based on.

See you


Fernando

One thought on “The Principles of Object-Oriented Design

  1. Nice post. I would add some advice to use the principles specially in moments of doubt. Use them as high level guidance to your design.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s