Skip to content

Instantly share code, notes, and snippets.

@vijayanant
Created September 17, 2017 04:23
Show Gist options
  • Save vijayanant/fda48ecfe22c170a12431b953f933ce4 to your computer and use it in GitHub Desktop.
Save vijayanant/fda48ecfe22c170a12431b953f933ce4 to your computer and use it in GitHub Desktop.
Rant about OO Design Principles (WIP)

Design Principles

There are many people who will say there are 5 design principles. Well, I believed that too for some time. There are a lot more design principles that you will be considering while designing an application/framework. But these are the few principles that you MUST adhere to in any application/framework class design.

These are the Principles of Object Oriented Class Design popularly known as the SOLID Principles.

  • The Single Responsibility Principle [SRP]
  • The Open/Closed Principle [OCP]
  • The Liskov Substitution Principle [LSP]
  • The Interface Segregation Principle [ISP]
  • The Dependency Inversion Principle [DIP]

Uniform Access Principle

The other important principles, less popularly known (and not asked in interviews) are related to packaging. Not to be confused with Java packages, Package here refers to a deployable component, or simply something you would 'release' for others to use - like a jar file. These are the Principles of Package Architecture aslo knows as Package Cohesion Principles.

  • The Release Reuse Equivalency Principle [REP]
  • The Common Closure Principle [CCP]
  • The Common Reuse Principle [CRP]
  • The Acyclic Dependencies Principle [ADP]
  • The Stable Dependencies Principle [SDP]
  • The Stable Abstractions Principle [SAP]

In this post I will try to give introduction to each of the above principles. Even though they all seem easy to grasp, it takes a lot of effort and practice to get them right.

I am planning on writing a series of posts explaining each principle in detail. I will come back and provide a link to the post when it is ready.

Principles of Object Oriented Class Design

The Single Responsibility Principle

A Class should have only one reason to change

According to this principle, a class should have a single responsibility. There should be only one reason for the class to change.

This means, in simple terms, every other class depending on this class uses it in the same way. As a result any change to the class doesn't break the code in unexpected places.

Contrast this with a class that has two (or more) responsibilities. When one of the responsibilities change, it may have an affect on classes that doesn't use (or depend on) that responsibility and they themselves need to be changed (unnecessarily).

The Open/Closed Principle

A module should be open for extension but closed for modification

The premise of open-closed principle is that one should not be changing the existing (working) code to incorporate the changes in requirement. Instead, the behavior of the class (or module) should be extended only by adding new code.

That means, classes and modules should be designed such that it is easy to extend the behavior and are closed for modification.

The Liskov Substitution Principle

Subclasses should be substitutable for their base classes

This may seem obvious, but there are subtleties that need to be considered. Subclassing may inherit the type of the base class but there is no guarentee that the subclass's behavior is consistant with what the application needs.

For example, it is common for sorting utilities to accept Comparators. In your application you can write custom comparator by implementing the Comparator interface. This is all fine, but application starts to behave weirdly if the custom comparator orders the elements in reverse order. This custom comparator is violating the LSP.

The Interface Segregation Principle

Clients should not be forced to depend upon interfaces that they do not use

I have spent considerable amount of time understanding how this principle is different from the SRP.

Some of my reasonings:

  1. Fat interfaces are sometimes inevitable (SRP does allow for carefully considered fat interaces) and ISP helps to keep things tidy under those circumstances.

The Dependency Inversion Principle

Depend upon Abstractions. Do not depend upon concretions

The aim of this principle is to make a class (or module) as independent as possible. An independent component is both easy to replace and reuse somewhere else.

In simple terms -

  • High level modules should not depend upon low level modules. Both should depend upon abstractions
  • Abstractions should not depend upon details. Details should depend upon abstractions

Principles of Package Architecture

The Release Reuse Equivalency Principle (REP)

_

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment