Additional Object Oriented Design Principles and Best Practices

Object Oriented Design principles are very important and are sometimes considered even more important than design patterns. All design patterns are based on one or more of the design principles. Having thorough understanding of the design principles will help you understand the design paterns better and faster, and will even help you solve many design scenarios if you can't find a design pattern fitting that scenario.

Below are some of the important design principles and design best practices that will help you create better designs. Please also see notes on SOLID Principles and What to avoid in your design.

  1. Program to interfaces

    • Program to an interface, not an implementation, as it will prevent any dependency on any specific implementation.

    • The interface here mean and abstraction and can be either an interface or an abstract class.

  2. Don’t repeat yourself (DRY)

    • ​​Avoid duplicating code. Move it into a separate function or class.

  3. Low coupling

    • Coupling is the degree to which one class knows about another class. If the knowledge is less, it is called loosely coupled. If knowledge is more, it is called tightly coupled.

    • Loose coupling is always preferred as it allow us to build flexible OO systems that can handle change.

    • For instance, if the knowledge of one class about other class is only through exposed interfaces (data hiding), the system is loosely coupled and easier to change than a system where classes access data members directly.

  4. Encapsulate what varies (EWV)

    • Identify the aspects of your application that vary, encapsulate them and separate them from what stays the same.

    • Head first design patterns book gives Duck example to demonstrate this. Consider the parent Duck has a method fly(), but then there are many type of Ducks that doesn't fly. One quick ineffective solution is to override this method in every subclass of Duck that does not fly, to do nothing. This will turn out to be nightmare when more and more Ducks are added. Instead, you can separate this fly behavior into a separate class backed by an interface and then every class that need this behavior can use this class.

  5. Prefer composition over inheritance

    • Classes may achieve polymorphic behavior and code reuse by containing other classes that implement the desired functionality instead of through inheritance.

    • You may have an abstract reference type (Program to Interfaces) and allow clients to change behavior at runtime by passing in any implementation. 

    • Using composition over inheritance also reduces code duplication.

    • Example 1: Stack class in Java is an example. It extends a List and exposes additional list methods which are not meant to be there for a stack. A better approach would have been to contain the list as a member and use it for storing the stack elements.

    • Example 2: In our previous Duck example (EWV), we can achieve this by having an interface reference for the fly behavior within Duck and based on the required fly behavior we can pass (or even inject) the correct implementation. Instead, if we had extended the Duck class with a fly behavior implementation, further extensions would have been difficult (against OCP). Also, if we had implemented an interface for fly behavior to allow further extensions, then every class would have had to overwrite it leading to code duplication (against DRY principle). 

  6. Keep it simple, stupid (KISS)

    • Simplicity should be a key goal in design and unnecessary complexity should be avoided. Many design patterns try to decompose the system into smaller sub systems to achieve this.

  7. Unit Testable

    • Every class should be testable independently without it invoking any other class.

    • If class A create and invoke another class B directly, then while unit testing class A, we will be also testing class B and hence technically it cannot be called unit test, but an integration test. If a class needs to create and invoke another class, we can use dependency injection to inject a constructed object (DIP) so that for unit testing you can pass in a dummy mock object.

 

Note: Latest version of this note can be found @ http://codingarchitect.com/additional-design-principles-and-best-practices.

References and notes: 
  1. Head First Design Patterns By Eric Freeman, Elisabeth Freeman, Bert Bates, Kathy Sierra

Quick Notes Finder Tags

Activities (1) advanced java (1) agile (3) App Servers (6) archived notes (2) Arrays (1) Best Practices (12) Best Practices (Design) (3) Best Practices (Java) (7) Best Practices (Java EE) (1) BigData (3) Chars & Encodings (6) coding problems (2) Collections (15) contests (3) Core Java (All) (55) course plan (2) Database (12) Design patterns (8) dev tools (3) downloads (2) eclipse (9) Essentials (1) examples (14) Exception (1) Exceptions (4) Exercise (1) exercises (6) Getting Started (18) Groovy (2) hadoop (4) hibernate (77) hibernate interview questions (6) History (1) Hot book (5) http monitoring (2) Inheritance (4) intellij (1) java 8 notes (4) Java 9 (1) Java Concepts (7) Java Core (9) java ee exercises (1) java ee interview questions (2) Java Elements (16) Java Environment (1) Java Features (4) java interview points (4) java interview questions (4) javajee initiatives (1) javajee thoughts (3) Java Performance (6) Java Programmer 1 (11) Java Programmer 2 (7) Javascript Frameworks (1) Java SE Professional (1) JPA 1 - Module (6) JPA 1 - Modules (1) JSP (1) Legacy Java (1) linked list (3) maven (1) Multithreading (16) NFR (1) No SQL (1) Object Oriented (9) OCPJP (4) OCPWCD (1) OOAD (3) Operators (4) Overloading (2) Overriding (2) Overviews (1) policies (1) programming (1) Quartz Scheduler (1) Quizzes (17) RabbitMQ (1) references (2) restful web service (3) Searching (1) security (10) Servlets (8) Servlets and JSP (31) Site Usage Guidelines (1) Sorting (1) source code management (1) spring (4) spring boot (3) Spring Examples (1) Spring Features (1) spring jpa (1) Stack (1) Streams & IO (3) Strings (11) SW Developer Tools (2) testing (1) troubleshooting (1) user interface (1) vxml (8) web services (1) Web Technologies (1) Web Technology Books (1) youtube (1)