Skip to main content

Design Pattern in Java

Why Design Pattern

In 1994, four authors Erich Gamma, Richard Helm, Ralph Johnson und John Vlissides published a book titled Design Patterns - Elements of Reusable Object-Oriented Software which initiated the concept of Design Pattern in Software development. The idea was to compile a list of common design patterns which can be used by programmers while designing the complex software. All the design patterns in this book are based on the two principles:
• Program to an interface, not an implementation.
• Favor object composition over inheritance.

Let's discuss these two principles in detail.

Program to an interface, not an implementation:
This principle means that when we create an object, we should create an object for the interface and not the implementation.

Example:
  • ArrayList myList = new ArrayList(); //Bad
  • List myList = new ArrayList(); //Good
  • List myList = new TreeList(); // Good
In this example, the first declaration is bad because if you plan to use tree list later. You need to change both the constructor and the variable type. On the contrary, if you plan to use the second or third declaration, then we only need to change the constructor in the declaration.

Favor object composition over inheritance:

The different classes can be related using two different ways - Composition or inheritance. If there is a choice between the two, try to use composition. Before we understand the importance of composition over inheritance, let's first discuss what is inheritance.

Inheritance:

Inheritance creates a "Is a" relationship between different classes. Let's take an example:
//Super Class
public class ClassC{

    public int methodC(){
    }
}

//Sub Class
public class ClassD extends ClassC {
    public void methodD() {
    }
}

//Test
public class Test{
    public static void main(String[] args) {
        ClassD obj = new ClassD();
        int output = obj.methodC();
    }
}

In this example, Class D extends Class C which means an object of Class D can access all the methods and variables of Class C. Let's say if we want to change the return type of methodC from int to String. It will break the code int the Class Test because it is expecting the return type as int. The composition can help us in this case. Let's see what a composition is and how can it be helpful.

Composition:

In composition, there exist a "Has a" relationship between two classes. It means one class contains an instance variable that holds the reference to another class. Let's take an example:

//Super Class
public class ClassC {
    public int methodC() {
    }
}

//Sub Class
public class ClassD {
    ClassC obj = new ClassC();

    public int methodCWrapper() {
        return obj.methodC();
    }

    public void methodD() {
    }
}

//Test
public class Test {
    public static void main(String[] args) {
        ClassD obj = new ClassD();
        int output = obj.methodCWrapper();
    }
}

In this example, Class D contains a constructor that takes an instance variable which is an object of the Super Class. Now, if we plan to change the return type of methodC from int to String we can do that without breaking the code in the Test class. We can make the changes in the methodCWrapper that will return the String to the method in the Test Class. In the change mentioned below, it can be seen that there was no change done in the Test class and code is still intact. That's why we should always prefer to use Composition as compared to inheritance for establishing a relationship between two or more classes.

//Super Class
public class ClassC {
    public String methodC() {
    }
}

//Sub Class
public class ClassD {
    ClassC obj = new ClassC();

// New change done here, so that no change is needed in
the client code in the test class.   
public int methodCWrapper() {
        return new Integer(obj.methodC()).toString();
    }

    public void methodD() {
    }
}

//Test
public class Test {
    public static void main(String[] args) {
        ClassD obj = new ClassD();
        int output = obj.methodCWrapper();
    }
}

In the next post, we will talk about the different types of design patterns.




Comments

  1. Great introduction to Java. Looking forward to reading more posts.

    ReplyDelete

Post a Comment

Popular posts from this blog

Java Virtual Machine

Java Virtual Machine I will start this blog with the details of Java Virtual Machine. This will help us understand the other important details of Java language in the coming posts. History: Java was developed by James Gosling  along with his peers at Sun MicroSystems in June 1991. The idea was to develop a language which allows an application programmer to write the code once and run it on different platforms without changing the source code. The problem with C/C++ languages is they follow the write once and compile anywhere philosophy which means you can write your source code once but it can be compiled on different machines. The issue is it can be compiled on the different machine but it cannot run on all the machines because the code is written to a specific operating system in mind. This problem is solved by Java Virtual machine which acts as an operating system to the application program and converts it into Java bytecode. This bytecode can run on any machine with any ...

Types of Design Patterns

Types of Design Patterns Creational Pattern: This design pattern covers the different ways to create an object. We will discuss all of them in the later posts of this blog: Builder Abstract Factory Factory Method Object Pool Prototype Singleton Structural Pattern: Once an object is created, the next job is to create a relationship between the different objects and it can be done using a structural design pattern. The different types of structural design patterns that we will discuss in the future posts are: Adapter Aggregate Bridge Composite Decorator Extensibility Facade FlyWeight Marker Pipes and Filter Opaque Pointer Proxy Behavioral Pattern: In the last two patterns, we have created an object and established a relationship between different objects. Now, we need to figure out ways to communicate with the different objects. Behavioral design pattern helps us in channelizing the communication between the newly created objects. The different ...