A good software developer builds a software using right design principles. If you learn design patterns, object oriented concepts, but don’t learn principles, then you will do a disservice to yourself as a developer. Without design principles, you will build a software with no heart, no functionality to serve. I hope you don’t want to do that.
In this post, I will try to explain some design principles that I have come across or learned through my experience. If you do not understand any of these principles, please comment on the post and I will answer your questions.
Programming for interface and not for implementation
While building design, you can think how you can reuse or design your code in a way where you can extend it in future if needed. OR you have to minimal changes if you have to change. One design principle that can help in such cases is to Program interfaces instead of implementation directly.
For variables, method return types or argument type of methods – use interfaces. This will help to implement interfaces as you want.
Single Responsibility Principle
A class, a method should always implement single responsibility or single functionality. Putting more than one functionality in an object can disturb the functionality in future if there are any changes. To reduce future changes, always create implement your code with single responsibility principle.
Liskov Substitution Principle
This principle states that objects should be replaceable with instances of their subclasses without altering the correctness of the program.
To understand this, let’s look at a simple object and subclasses of that object Bird
public class Bird { void fly() { // Fly function for bird } } public class Parrot extends Bird { @Override void fly() { } } public class Ostrich extends Bird { // can't implement fly since Ostrich doesn't fly }
Parrot as a bird can fly, but Ostrich as a bird can’t fly. So if we end up using such an implementation, it will violate the principle of Liskov Substitution.
Open Closed Principle
Open Closed Principle makes that objects,methods should be open for extensions, but closed for modification. Many times, requirements are not clear at the beginning of design and implementation, we must use open closed principle to implement initial design and slowly if requirements change, it becomes easy to add them in design.
Interface Segregation Principle
This principle requires that client should not be forced to implement interface if it doesn’t use that. In another words, make sure your interfaces are concise and implement single functionality only. If interface has more than one functionality, it can be unnecessary for client to implement all the functionalities when it only needs one.
Delegation Principle
Don’t do all the stuff by yourself, but delegate the functionalities to respective classes. Delegation is kind of relationship between objects where an object can forward certain functions to do work to other objects (provided those objects implement those functions).
Dependency Inversion Principle
This principle is type of decoupling behavior for software modules. High level modules should not depend on low level modules. Generally while designing high level classes will depend on low level classes. But if you have to change low level classes after every design revision, it will warrant to be a bad design. To avoid such a problem, we create an abstraction layer. Low level classes will be created based on abstraction layer.
When this principle is used, high level classes use interfaces as an abstraction layer to work with low level classes, instead of working directly with low level classes.
References
- Ten object oriented design principles – SOLID Principles
- Design Principles – design principles