Saturday 6 January 2018

Design Patterns | Memento Design Pattern in Java

The memento pattern is a software design pattern that provides the ability to restore an object to its previous state (undo via rollback).

The intent of the memento pattern is to capture the internal state of an object without violating encapsulation so that the object can be restored to required previous state.

Memento pattern is used to implement this in such a way that the saved state data of the object is not accessible outside of the object; this protects the integrity of saved state data.

Database Transactions
Mechanism of rolling back the transaction can be achieved by memento design pattern.

Participants
The classes and objects participating in this pattern are:
Memento - It is a POJO which maintains the state of the originator.
Originator - The originator is some object that has an internal state.
Caretaker - Caretaker is the object that keeps track of multiple mementos. It maintains the mementos like save points.


Example of memento pattern
Most of the editors use the memento pattern to store the previous states so user can restore them when it required. Like in notepad, 'Ctrl+Z' is used to Undo an action and 'Ctrl+Y' is used to Redo the last action or repeat an action.

Memento.java
public class Memento {
      private String state;

      public Memento(String state){
            this.state = state;
      }

      public String getState(){
            return state;
      }    
}

FileWriterUtil.java
public class FileWriterUtil {
      private String state;

      public void setState(String state){
            this.state = state;
      }

      public String getState(){
            return state;
      }

      public Memento saveStateToMemento(){
            return new Memento(state);
      }

      public void getStateFromMemento(Memento Memento){
            state = Memento.getState();
      }
}

FileCareTaker.java
import java.util.ArrayList;
import java.util.List;

public class FileCareTaker {
     
      private List<Memento> mementoList = new ArrayList<Memento>();

      public void add(Memento state){
            mementoList.add(state);
      }

      public Memento get(int index){
            return mementoList.get(index);
      }
}

FileHandlerClient.java
public class FileHandlerClient {
      public static void main(String[] args) {

            FileWriterUtil originator = new FileWriterUtil();
           
            FileCareTaker careTaker = new FileCareTaker();

            originator.setState("State#1");
           
            originator.setState("State#2");
            /*save the current state. i.e#State#2*/
            careTaker.add(originator.saveStateToMemento());

            originator.setState("State#3");
            /*save the current state. i.e#State#3*/
            careTaker.add(originator.saveStateToMemento());

            originator.setState("State#4");
            System.out.println("Current State: " + originator.getState());         

            originator.getStateFromMemento(careTaker.get(0));
            System.out.println("First saved State: " + originator.getState());
           
            originator.getStateFromMemento(careTaker.get(1));
            System.out.println("Second saved State: " + originator.getState());
      }
}

Output:
Current State: State#4
First saved State: State#2
Second saved State: State#3

The examples in Java's core libraries
java.util.Date (the setter methods do that, Date is internally represented by a long value)
All implementations of java.io.Serializable
All implementations of javax.faces.component.StateHolder.

Important points

Memento pattern is very easy to implement, however, we need to take care that Memento class should be accessible by Originator object only. We should use the caretaker object for saving and restoring the originator state.

Sometimes Originator object has properties that are not immutable; we should use deep copy or cloning to avoid data integrity and security issue. If deep cloning is very complex, Serialization is the best way to achieve this.

One drawback of this pattern, if Originator object is very huge then Memento object size will also be huge and use a lot of memory.

Thursday 4 January 2018

Design Patterns | Facade pattern

The facade pattern is a wrapper of many other interfaces in a result to produce a simpler interface.

Facade hides the complexities of the system and provides an interface to the client from where the client can access the system easily. A facade is an object that provides a simplified interface to a larger body of code, such as a class library.






Example
This is an abstract example of how a client ("you") interacts with a facade (the "computer") to a complex system (internal computer parts, like CPU and HardDrive).

/* Complex parts */
class CPU {
      public void freeze() {
            ...
      }
      public void jump(long position) {
            ...
      }
      public void execute() {
            ...
      }
}

class Memory {
      public void load(long position, byte[] data) {
            ...
      }
}

class HardDrive {
      public byte[] read(long lba, int size) {
            ...
      }
}

/* Facade */

class ComputerFacade {
      private CPU processor;
      private Memory ram;
      private HardDrive hd;

      public ComputerFacade() {
            this.processor = new CPU();
            this.ram = new Memory();
            this.hd = new HardDrive();
      }

      public void start() {
            processor.freeze();
            ram.load(BOOT_ADDRESS, hd.read(BOOT_SECTOR, SECTOR_SIZE));
            processor.jump(BOOT_ADDRESS);
            processor.execute();
      }
}

/* Client */

class Facade {
      public static void main(String[] args) {
            ComputerFacade computer = new ComputerFacade();
            computer.start();
      }
}

Points to remember about façade design pattern
1. Wrap a poorly designed collection of APIs with a single well-designed API.
2. Reduce dependencies of outside code on the inner workings of a library, since most code uses the facade, thus allowing more flexibility in developing the system;
3. Facade design pattern is more like a helper for client applications; it doesn’t hide subsystem interfaces from the client. Whether to use Facade or not is completely dependent on the client code.
4. Facade design pattern can be applied at any point of development, usually when the number of interfaces grows and the system gets complex.
5. Subsystem interfaces are not aware of Facade and they shouldn’t have any reference to the Facade interface.

We can use Factory Pattern with Facade to provide a better interface to client systems.

Sources

Related Posts Plugin for WordPress, Blogger...