June 19, 2016

Object Oriented Design Principles in Java

The Object-Oriented Design Principles are the core of Object Oriented Programming, with their help we can create a clean and modular design, which would be easy to test, debug, and maintain.

We can say the design principles are generalized pieces of advice or proven good coding practices that can be used as rules of thumb while making design choices.


What is the difference between a design patterns and design principle?
Design principles are more abstract and generalized. They are high-level pieces of advice, which are often applicable to many different programming languages or even different paradigms.

Design patterns are also abstract and generalized, but they provide much more concrete and practical low-level advice, and are related to entire classes of problems rather than just generalized coding practices.

Name some of the important design principles in the object oriented paradigm.
  • Don't Repeat Yourself (DRY) Principle
  • Keep It Simple and Stupid (KISS) Principle
  • The Single Responsibility Principle (SRP)
  • The Open/Closed Principle
  • Liskov Substitution Principle (LSP)
  • The Interface Segregation Principle (ISP)
  • The Dependency Inversion Principle (DIP)
  • The Composition Over Inheritance Principle
The SRP, LSP, Open/Closed, and DIP principles are often bundled together and called SOLID principles.

What is SOLID principle in Java? Or What is open closed design principle in Java?
1). Single Responsibility Principle : One class should have one and only one responsibility. We should write, change and maintain a class for only one purpose.

2). Open Closed Principle : Software components should be open for extension, but closed for modification. It means that your classes should be designed in such a way that whenever fellow developers wants to change the flow of control in specific conditions in application, all they need to extend your class and override some functions and that’s it. If other developers are not able to design desired behavior due to constraints put by your class, then you should reconsider changing your class.


3). Liskov’s Substitution Principle : Derived types must be completely substitutable for their base types. It means that the classes fellow developer created by extending your class should be able to fit in application without failure. i.e. if a fellow developer poorly extended some part of your class and injected into framework/ application then it should not break the application or should not throw fatal exceptions.

4). Interface Segregation Principle : It is applicable to interfaces as single responsibility principle holds to classes. Clients should not be forced to implement unnecessary methods which they will not use. e.g: If you created an interface Reportable and added two methods generateExcel() and generatedPdf(). Now another developer wants to use this interface but he intend to use reports only in PDF format and not in excel. He will have to implement two methods, out of which one is extra burden put on him by designer of software. Either he will implement another method or leave it blank. Which is wrong. Instead of one interface, we should create two interfaces by breaking the existing one. They should be like PdfReportable and ExcelReportable. This will give the flexibility to user to use only required functionality only.

5). Dependency Inversion Principle : Depend on abstractions, not on concretions. We should design our software in such a way that various modules can be separated from each other using an abstract layer to bind them together.

Don't Repeat Yourself (DRY) Principle
  • As the name suggests it means don't write duplicate code, instead use Abstraction to abstract common things in one place. 
  • Every piece of knowledge or logic must have a single, unambiguous representation within a system. If you have a block of code in more than two places, consider making it a separate method.
  • Duplication is not for code, but for functionality also.
  • In case of OOP, we should use abstract classes, interfaces, and public constants. Whenever there's a functionality common across classes, it either might make sense to abstract them away into a common parent class or use interfaces to couple their functionality. 
  • Whenever there's a constant that's used multiple times, it's good practice to define it as a public constant. Due to the naming convention in Java, 'public constant should be capitalized with words separated by an underscore and must be 'final'.
WET
Violations of the DRY Principle are often referred to as WET solutions. WET can be an abbreviation for multiple things: We Enjoy Typing, Waste Everyone's Time, Write Every Time, Write Everything Twice etc.

Well, WET solutions aren't always bad, as repetition is sometimes advisable in inherently dissimilar classes, or in order to make code more readable, less inter-dependent, etc.

Keep It Simple and Stupid (KISS) Principle

  • KISS design principle says that that most software, program works well if they are made simple rather than complex.
  • It's a reminder to keep your code simple and readable for humans. Unreadable and long methods are very hard to maintain, bugs will be harder to find.
  • If your method handles multiple use-cases, split them into smaller functions rather writing a method of 3000 lines. 
  • If a method performs multiple functionalities, make multiple methods instead for each functionality.

The Composition Over Inheritance Principle
  • We should often prefer composition over inheritance when designing their systems.
  • Inheritance and composition relationships are also referred as IS-A and HAS-A relationships.
  • In Java, we should more often define interfaces and implement them, rather than defining classes and extending them.
  • In composition, a class, which desire to use functionality of an existing class, doesn't inherit, instead it holds a reference of that class in a member variable. 
  • In Inheritance, an instance of sub class can be passed to a method, which accepts instance of super class.
  • A super class reference variable can refer to an instance of sub class. By using composition, you don’t get this behavior, but still it offers a lot more to tilde the balance in its side.
Reasons to prefer Composition over Inheritance in Java?
1). Java doesn't support multiple inheritance. If you need multiple functionality like e.g. for reading and writing character data into file, we need Reader and Writer functionality and having them as private members will make our job easy. We can use interface and provide different Reader and Writer implementation at different situation. But we won’t get this flexibility by using Inheritance, because in case of extending a class, we only get facilities which are available at compile time.

2). Better test-ability is offered by Composition, we can easily Mock Object representing composed class for sake of testing. Inheritance doesn't provide this facility. In order to test derived class, we must need its super class.

3). Composition provides flexibility, we can easily replace implementation of Composed class with better and improved version.

-K Himaanshu Shuklaa..

No comments:

Post a Comment