10 Object Oriented Design Principles Java Programmer should know

The Object-Oriented Design Principles are the core of OOP programming, but I have seen most of the Java programmers chasing design patterns like Singleton pattern, Decorator pattern or Observer pattern, and not putting enough attention on learning Object-oriented analysis and design. It's important to learn basics of Object-oriented programming like Abstraction, Encapsulation, Polymorphism, and Inheritance. But, at the same time, it's equally important to know object-oriented design principles, to create the clean and modular design. I have regularly seen Java programmers and developers of various experience level, who either don't hear about these OOP and SOLID design principle, or simply doesn't know what benefits a particular design principle offers, or how to apply these design principle in coding. 

Bottom line is, always strive for highly cohesive and loosely couple solution, code or design. Looking open source code from Apache and Sun are good examples of learning Java and OOP design principles.

They show us,  how design principles should be used in coding and Java programs. Java Development Kit follows many design principles like Factory Pattern in BorderFactory class,  Singleton pattern in Runtime class, Decorator pattern on various java.io classes.

If you are interested in learning object-oriented principles and patterns, then you can look at my another personal favorite Head First Object Oriented Analysis and Design, an excellent book and probably the best material available in object-oriented analysis and design

Not many programmers know this book because it is often shadowed by its more popular cousin Head First Design Pattern by Eric Freeman, which is more about how these principles come together to create a pattern you can use directly to solve known problems.

These books help a lot to write better code, taking full advantage of various Object-oriented and SOLID design principles.

Btw, if you really interested more in Java coding practices then read Effective Java 3rd Edition by Joshua Bloch, a gem by the guy who wrote Java Collection API.




10 Object Oriented and SOLID Desing Principles for Programmers

Object oriented design principles and pattern in Java programmingThough best way of learning any design principle or pattern is a real-world example and understanding the consequences of violating that design principle, subject of this article is Introducing Object-oriented design principles for Java Programmers, who are either not exposed to it or in the learning phase. 

I personally think each of these OOP and SOLID design principle needs an article to explain them clearly, and I will definitely try to do that here, but for now just get yourself ready for quick bike ride on design principle town :)


DRY (Don't repeat yourself)

Our first object-oriented design principle is DRY, as the name suggests DRY (don't repeat yourself) means don't write duplicate code, instead use Abstraction to abstract common things in one place. If you have a block of code in more than two places consider making it a separate method, or if you use a hard-coded value more than one time make them public final constant.

The benefit of this Object oriented design principle is in maintenance. It's important not to abuse it, duplication is not for code, but for functionality. It means if you used common code to validate OrderID and SSN it doesn’t mean they are same or they will remain same in future.

 Object Oriented Design Principles Java Programmer should know

By using common code for two different functionality or thing you closely couple them forever and when your OrderID changes its format, your SSN validation code will break.

So beware of such coupling and just don’t combine anything which uses similar code but are not related. You can further check out Basics of Software Architecture & Design Patterns in Java course on Udemy to learn more about writing good code. 



Encapsulate What Changes

Only one thing is constant in software field and that is "Change", So encapsulate the code you expect or suspect to be changed in future. The benefit of this OOP Design principle is that It's easy to test and maintain proper encapsulated code.

If you are coding in Java then follow the principle of making variable and methods private by default and increasing access step by step e.g. from private to protected and not public.

SOLID design principles for programmers


Several of the design patterns in Java uses Encapsulation, Factory design pattern is one example of Encapsulation which encapsulates object creation code and provides flexibility to introduce a new product later with no impact on existing code.


Open Closed Design Principle

Classes, methods or functions should be Open for extension (new functionality) and Closed for modification. This is another beautiful SOLID design principle, which prevents someone from changing already tried and tested code.

Open Closed Design Principle


Ideally, if you are adding new functionality only than your code should be tested and that's the goal of Open Closed Design principle. By the way, Open Closed principle is "O" from the SOLID acronym.



Single Responsibility Principle (SRP)

Single Responsibility Principle is another SOLID design principle, and represent  "S" on the SOLID acronym. As per SRP, there should not be more than one reason for a class to change, or a class should always handle single functionality.

Single Responsibility Principle (SRP)


If you put more than one functionality in one Class in Java it introduces coupling between two functionality and even if you change one functionality there is a chance you broke coupled functionality,  which requires another round of testing to avoid any surprise on the production environment.

You can further see From 0 to 1: Design Patterns - 24 That Matter course on Udemy to learn about patterns which are based on this principle. 


Dependency Injection or Inversion principle

Don't ask for dependency it will be provided to you by the framework. This has been very well implemented in Spring framework, the beauty of this design principle is that any class which is injected by DI framework is easy to test with the mock object and easier to maintain because object creation code is centralized in the framework and client code is not littered with that.

Dependency Injection or Inversion principle


There are multiple ways to implemented Dependency injection like using byte code instrumentation which some AOP (Aspect Oriented programming) framework like AspectJ does or by using proxies just like used in Spring. See this example of IOC and DI design pattern to learn more about this SOLID design principle. It represents "D" on the SOLID acronym.



Favor Composition over Inheritance

Always favor composition over inheritance, if possible. Some of you may argue this, but I found that Composition is the lot more flexible than Inheritance.

Composition allows changing behavior of a class at run-time by setting property during run-time and by using Interfaces to compose a class we use polymorphism which provides flexibility of to replace with better implementation any time.

Favor Composition over Inheritance



Even Effective Java advise favoring composition over inheritance. See here to learn more about why you Composition is better than Inheritance for reusing code and functionality. 


Liskov Substitution Principle (LSP)

According to Liskov Substitution Principle, Subtypes must be substitutable for supertype i.e. methods or functions which uses superclass type must be able to work with the object of subclass without any issue".

 LSP is closely related to Single responsibility principle and Interface Segregation Principle. If a class has more functionality than subclass might not support some of the functionality and does violate LSP.

Liskov Substitution Principle (LSP)


In order to follow LSP SOLID design principle, derived class or subclass must enhance functionality, but not reduce them. LSP represents "L" on the SOLID acronym.  If you are interested in a more real-world example, then SOLID Principles of Object Oriented Design course on Pluarlsight is a good course to start with. 


Interface Segregation Principle (ISP)

Interface Segregation Principle stats that, a client should not implement an interface if it doesn't use that. This happens mostly when one interface contains more than one functionality, and the client only needs one functionality and no other.

Interface design is a tricky job because once you release your interface you can not change it without breaking all implementation.

Interface Segregation Principle (ISP)


Another benefit of this design principle in Java is, the interface has the disadvantage to implementing all method before any class can use it so having single functionality means less method to implement. If you don't the get the benefit of the interface in coding then I suggest you read my blog post, the real usage of an interface in Java to learn more. 


Programming for Interface not implementation

Always program for the interface and not for implementation this will lead to flexible code which can work with any new implementation of the interface.

So use interface type on variables, return types of method or argument type of methods in Java.


This has been advised in many Java books including in Effective Java and Head First design pattern book.





Delegation principles

Don't do all stuff by yourself,  delegate it to respective class. Classical example of delegation design principle is equals() and hashCode() method in Java. In order to compare two objects for equality, we ask class itself to do comparison instead of Client class doing that check.

The key benefit of this design principle is no duplication of code and pretty easy to modify behavior. Event delegation is another example of this principle, where an event is delegated to handlers for handling. 

Delegation principle in Java


Summary

All these object-oriented design principles help you write flexible and better code by striving high cohesion and low coupling. The theory is the first step, but what is most important is to develop the ability to find out when to apply these design principle. Once you get hold of that, next step is to Experience Design Patterns In Java

Here is a nice summary of all these OOP design principles.

Object oriented and SOLID design principle in Java


Find out, whether we are violating any design principle and compromising flexibility of code, but again as nothing is perfect in this world, don't always try to solve the problem with design patterns and design principle they are mostly for large enterprise project which has longer maintenance cycle.

Other Java and Programming Resources you may like
From 0 to 1: Design Patterns - 24 That Matter - In Java
10 Books Every Programmer Must Read
10 Tips to Improve Your Programming skill
10 Tools Every Software Developer should know
Top 10 Programming languages to Learn
10 Articles Every Programmer Should Read
10 Framework and Library Java and Web Developer Should Learn

Thanks for reading this article. If you find these object-oriented design principles useful then please share with your friends and colleagues. If you have any questions or feedback then please drop a note.

20 comments :

Anonymous said...

Excellent Article.....!!!!!but these concepts can be learned by experience...Hopefully I am trying to applying the things which I learnt.

But I hope you are going to post few articles regarding the OOPS concept and design principles.

Ajith said...

awesome blogs .. Hats of to you Javin....You are taking this to a whole new level..I was asked this question in a BNY /Mellon interview and i wish i could answer it this clearly!!!!

Anonymous said...

Very simple great impact !!!

Haitham Raik said...

Very great article.


But lets not forget the basic design principle:

KISS: Keep It Simple and Straightforward; simplicity should be a key goal in design and unnecessary complexity should be avoided

Anonymous said...

Some quick notes:
DRY is not exactly an object oriented principle, isn't it? Nor is it one of the SOLID principles.

Dependency injection and Inversion (of Control) are not equal. Moreover you do not need a framework to do dependency injection.

As its name suggests ISP is rather the other way round: Break up a single (big) interface into small ones. Maybe you meant the right thing and your definition is just confusing.

Equals() and hashCode() are good examples of encapsulation and information hiding rather than delegation.

"... design patterns and design principle ... are mostly for large enterprise project which has longer maintenance cycle"
That is like saying a healthy lifestyle is only important for athletes. You seem to confuse basic patterns and principles with sophisticated designs. Plus: The length of a maintenance cycle does not correlate with the size of a project.

It's good for less experienced developers, though, to see many important principles in one place. Keep on going.

Javin @ design pattern interview question said...

@Anonymous, Thanks for your comment. DRY (Don't repeat yourself) is more of pattern derived from Experience, but its mostly referenced along with other SOLD design principles.

Regarding DI, isn't it an example of Inversion of Control where dependency is injected by external source like Spring framework instead of hard coded, though I agree that you can write your own framework to implement Dependency Injection but I still see better to use Spring framework than creating your own as you can never get same level of testing, quality and stability as front line open source project like Spring gains.

Regarding equals() and hashCode() indeed they better fit and example of encapsulation rather than delegation.

Anyway Thanks for your input and comment, keep it coming.

Anonymous said...

Sounds as if these examples were taken from " Head First Object-Oriented Analysis and Design". A great book BTW, worth mentioning here :-)

Anonymous said...

How about adding few more design principles :

KISS (Keep it Simple, Stupid)- KISS design principle says that that most software, program works well if they are made simple rather than complex.

YAGNI - You are not going to need it, is an extreme programming design principle which states that don't build any functionality until you need it. this is best to remove dead code or not utilized code from your project.



Anonymous said...

Superb stuff

Anonymous said...

Please don't confuse dependency inversion (DIP) and dependency injection - they are two totally different principles. See http://martinfowler.com/articles/dipInTheWild.html for explanation.

Pattision said...

Hello there, what is difference between design principle and design patterns? Can you please describe?

Tanzy said...

Hi Pattision,

Basically design principles are the base on which design patterns get created to solve a problem.

More details can be found here-
http://techythought.wordpress.com/2013/01/21/design-principle-vs-ds-design-pattern-describing-oop-elements/

Murali Mohan Reddy said...

HI Javin, Please try to post an article Design Principles Vs Design Patterns? People often confusing about principles and patterns are same or not. Could be highly appreciate if you can post an article.

Anonymous said...

good theory but can you publish practical programs of above 10 points.it will be helpful also.

Anonymous said...

a great article, every java developer and designer must definitely read this.

K. Ravi said...

Good list, though I know these principles and patterns and what problem they solve, having them in one place is great job. In real life there are more principle, rules than these though, for example I would like to share one design pattern, principle or rule, call it whatever you like, which has benefited me lot in past.

One of the keys to write robust and flexible software is to make sure that layers at the bottom that are reusable have no knowledge of the layers that use them.

For example, the Logger classes have no knowledge of any other class that uses them. This lets the class designers focus on the Logging functionality.

anish gupta said...

Excellent Article.....!!!! here i've seen most them taking hashCode() and equals(-) method into the criteria of encapsulatio rather than delegation so here we can also keep toString() method as the example of encapsulation design pattern .............. m i ri8 or wrong..........

mufeez ahmed said...

Thanks for the article ,it made me realise the importance of design principles

Anonymous said...

Ganesh : Super se Uper...:)

DEEPAK SHUKLA said...

Awesome post

Post a Comment