Monday, 15 January 2018

Design Patterns | Adapter design pattern

In the real-world, Adapter allows two incompatible interfaces to work together. Interfaces may be incompatible, but the inner functionality should suit the need.

The adapter pattern is a software design pattern that allows incompatible classes to work together by converting the interface of one class into an interface expected by the clients. It is often used to make existing classes work with others without modifying their source code. This pattern is also known as Wrapper.



Participants
The participant classes and objects are,

Target Interface
This is the domain-specific used by the clients.
Adapter class
A wrapper class implements the target interface and modifies Adaptee to the Target interface.
Adaptee class
The class which is used by the Adapter to reuse the existing functionality and modifies them for the desired use.
Client
This class will interact with the Adapter class using Target interface.

Real life example
Mobile battery needs 5V to charge but the normal socket produces either 220V (India) or 110V~120V (USA). To provide the Targeted power (5V), we use the Mobile charger to charge the battery. Mobile charger works as an adapter between mobile charging socket and the wall socket.

public class Volt {
    private int volts;

    public Volt(int v) {
        this.volts = v;
    }

    public int getVolts() {
        return volts;
    }

    public void setVolts(int volts) {
        this.volts = volts;
    }
}

/**
 * Common interface.
 */
public interface ISocketAdapter {
    public Volt getVolt();
}

/**
 * This is the Adaptee class.
 */
public class WallSocketAdaptee {
    public Volt getVolt() {
        return new Volt(120);
    }
}

/**
 * Adapter class which has is working as converter.
 */
public class SocketClassAdapterImpl extends WallSocketAdaptee implements ISocketAdapter {

    @Override
    public Volt getVolt() {
        Volt v = getVolt();
        return convertVolt(v, 24);
    }

    private Volt convertVolt(Volt v, int i) {
        return new Volt(v.getVolts() / i);
    }
}

public class AdapterClient {

    /** Volts from Adapter. */
    private static void testAdapter() {
        ISocketAdapter sockAdapter = new SocketClassAdapterImpl();
        Volt volt = sockAdapter.getVolt();
        System.out.println("Adapter producing " + volt.getVolts());
    }
   
    /** Driver method. */
    public static void main(String[] args) {
        testAdapter();
    }
}

The Adapter design pattern solves problems like,
1. How can a class be reused that does not have an interface that a client requires?
2. How can classes that have incompatible interfaces work together?
3. How can an alternative interface be provided for a class?
Often an (already existing) class can't be reused only because its interface doesn't conform to the interface clients require.

The Adapter design pattern describes how to solve such problems
1. Define a separate Adapter class that converts the (incompatible) interface of a class (Adaptee) into another interface (Target) clients require.
2. Work through an Adapter to work with (reuse) classes that do not have the required interface.

The key idea in this pattern is to work through a separate Adapter that adapts the interface of an (already existing) class without changing it. Clients don't know whether they work with a Target class directly or through an Adapter with a class that does not have the Target interface.

Adapter pattern use in the Java Libraries
java.util.Arrays#asList().
java.util.Collections#list().
java.util.Collections#enumeration().
java.io.InputStreamReader(InputStream) (returns a Reader).
java.io.OutputStreamWriter(OutputStream) (returns a Writer).
javax.xml.bind.annotation.adapters.XmlAdapter#marshal() and #unmarshal().

Design Patterns | State Design Pattern

Allow an object to alter its behavior when it’s internal state changes. The object will appear to change its class.

State pattern is one of the behavioral design patterns which is used when an Object changes its behavior based on its internal state. 

If we need to change the behavior of an object based on its state, we can define state variable in the Object and use if-else condition block to perform different actions based on the state. This approach is inflexible as we need to add an if-else block in the class for the new stateHowever, State pattern is used to provide a systematic and loosely-coupled way to achieve this (state change) through Context and State implementations.

Participants
The classes and objects participating in state design pattern:
Context
It defines the interface of interest to clients and maintains an instance of a ConcreteState subclass that defines the current state.

State
It defines an interface for encapsulating the behavior associated with a particular state of the Context.

ConcreteState
Each subclass implements a behavior associated with a state of Context.

What problems can the State design pattern solve?
1. An object should change its behavior when it’s internal state changes.
2. State-specific behavior should be defined independently. That is, new states should be added and the behavior of existing states should be changed independently.

Implementing state-specific behavior directly (using if-else block) within a class is inflexible because it commits the class to a particular behavior and makes it impossible to add a new state or change the behavior of an existing state later without changing the class (developers need to add a new if-else block for new state).

What solution does the State design pattern describe?
1. Define separate (state) objects that encapsulate state-specific behavior for each state. That is, define an interface (State) for performing the state-specific behavior, and define classes that implement the interface for each state.
2. A class delegates state-specific behavior to its current state object instead of implementing state-specific behavior directly.

This makes a class independent of how state-specific behavior is implemented. New states can be added by defining new state classes. A class can change its behavior at run-time by changing its current state object.

Sunday, 14 January 2018

Design Patterns | Abstract Factory Pattern

Abstract Factory Pattern is a creational design pattern. It is almost similar to Factory Pattern with another layer of abstraction over factory pattern. Abstract Factory patterns work around a super-factory which creates other factories.

According to the Gang of Four

Provide an interface for creating families of related or dependent objects without specifying their concrete classes.

Intent
Provide an interface for creating families of related or dependent objects without specifying their concrete classes.

Abstract factory pattern provides a way to encapsulate a group of individual factories that have a common theme. It provides an interface (or abstract class) for creating families of related or dependent objects without specifying their concrete classes.

Abstract Factory Pattern is almost similar to Factory Pattern with one more abstraction layer over factory pattern and this layer provides the factory of the factories.



Participants
The classes and objects participating in this pattern are:
AbstractFactory
It declares an interface for operations that create abstract products.
ConcreteFactory
This class implements the operations to create concrete product objects
AbstractProduct
It declares an interface for a type of product object.
Product
It defines a product object to be created by the corresponding concrete factory and implements the AbstractProduct interface.
Client
The client uses interfaces declared by AbstractFactory and AbstractProduct classes.

Abstract Factory Design Pattern in Java Libraries
javax.xml.parsers.DocumentBuilderFactory#newInstance()
javax.xml.transform.TransformerFactory#newInstance()
javax.xml.xpath.XPathFactory#newInstance().

Design Patterns | Strategy Pattern (Policy Pattern)

Strategy pattern is used when we have multiple algorithms for a specific task and client decides the actual implementation need to be used at runtime.


The strategy pattern defines multiple algorithms/classes, encapsulates each algorithm, and makes the algorithms interchangeable within that family. Strategy lets the algorithm vary independently from clients that use it.

To make the algorithms interchangeable, client application passes the algorithm to be used as a parameter.

Example
Collections.sort() method that takes Comparator parameter. The list can be sorted in different ways using different implementations of Comparator interfaces.


Elements Strategy Pattern
Strategy
 (SortStrategy)
It is a Common Interface that implemented by to all supported algorithms (ConcreteStrategy).

ConcreteStrategy (BuubleSort, QuickSort, MergeSort)
This class implements the algorithm using the SortStrategy interface.

Context (SortList)
It maintains a reference to a Strategy object and logic to use the Strategy object.

package com.algorithm;

interface SortStrategy {
      public void sort(int[] numbers);
}

class BubbleSort implements SortStrategy {
      @Override
      public void sort(int[] numbers) {
            System.out.println("Buuble sort !!");
      }
}

class QuickSort implements SortStrategy {
      @Override
      public void sort(int[] numbers) {
            System.out.println("Quick sort !!");
      }
}

class MergeSort implements SortStrategy {
      @Override
      public void sort(int[] numbers) {
            System.out.println("Merge sort !!");
      }
}

class SortList {
     
      private final SortStrategy strategy;

      public SortList(SortStrategy strategy) {
            this.strategy = strategy;
      }

      public void arrange(int[] input) {
            strategy.sort(input);
      }
}

public class StrategyTest {
      public static void main(String args[]) {

            int[] var = { 1, 2, 3, 4, 5 };

            /** Define Bubble sort to at run time. */
            Context ctx = new Context(new BubbleSort());
            /** Change the strategy without changing Context. */
            ctx.arrange(var);

            /** Define Quick sort to at run time. */
            ctx = new Context(new QuickSort());
            ctx.arrange(var);
      }
}
Output:
      Buuble sort !!
      Quick sort !!

What problems can the Strategy design pattern solve?
1. A class should be configured with an algorithm instead of implementing an algorithm directly.
2. An algorithm should be selected and exchanged at run-time.

What is an algorithm?
An algorithm is a procedure that takes some value as input, performs a finite number of steps, and produces some value as output. From a more general perspective, an algorithm is a piece of code that does something appropriate.

Implementing an algorithm directly within the class that uses the algorithm is inflexible because it commits the class to a particular algorithm at compile-time and makes it impossible to change the algorithm later independently from (without having to change) the class. This also stops the class from being reusable when another algorithm should be used.

What solution does the Strategy design pattern describe?
1. Define a separate (strategy) object that encapsulates an algorithm.
2. A class delegates an algorithm to a strategy object at run-time instead of implementing an algorithm directly (that is, instead of committing to an algorithm at compile-time).

Strategy pattern use in Java Libraries?
1. java.util.Comparator#compare(), executed by among others Collections#sort().
2. javax.servlet.http.HttpServlet, the service() and all doXXX() methods take HttpServletRequest and HttpServletResponse and the implementor has to process them.
3. javax.servlet.Filter#doFilter().


Related Posts Plugin for WordPress, Blogger...