Sunday, September 7, 2014

Behavioral patterns in Java - Part 1

From wikipedia:
In software engineering, behavioral design patterns are design patterns that identify common communication patterns between objects and realize these patterns. By doing so, these patterns increase flexibility in carrying out this communication.
Examples of this type of design pattern include:
  • Chain of responsibility pattern: Command objects are handled or passed on to other objects by logic-containing processing objects
  • Command pattern: Command objects encapsulate an action and its parameters
  • "Externalize the Stack": Turn a recursive function into an iterative one that uses a stack[1]
  • Interpreter pattern: Implement a specialized computer language to rapidly solve a specific set of problems
  • Iterator pattern: Iterators are used to access the elements of an aggregate object sequentially without exposing its underlying representation
  • Mediator pattern: Provides a unified interface to a set of interfaces in a subsystem
  • Memento pattern: Provides the ability to restore an object to its previous state (rollback)

1. Chain of responsibility

Actors: list (chain) of command objects. Command can have link to "next"(in chain) command.  

Goal: each command tries to do some action and switch execution process to next command.

Main class:


public class ChainOfResponsibility {
    
    public abstract class AbstractCommand {
        public abstract String executeInternal();
        
        AbstractCommand next;
        String name;
        
        public void setName(String name) {
            this.name=name;
        }
        
        public void setNext(AbstractCommand next) {
            this.next=next;
        }
                
        
        public String execute(String commands) {
            String result="";
            if (commands.indexOf(name)>-1) {
                result=executeInternal();
            }           
            if (next!=null) {
                result=result+"."+next.execute(commands);
            }
            return result;
        }
        
    }

    public class CreateCommand extends AbstractCommand {

        @Override
        public String executeInternal() {
            return "create";
        }       
        
    }   
    
    public class DrawCommand extends AbstractCommand {

        @Override
        public String executeInternal() {
            return "draw";
        }       
        
    }
    
    public class MoveCommand extends AbstractCommand {

        @Override
        public String executeInternal() {
            return "move";
        }       
        
    }
    
    public class Client {
        public String execute(String commands) {
            
            CreateCommand createCommand=new CreateCommand();
            createCommand.setName("create");
            
            DrawCommand drawCommand=new DrawCommand();
            drawCommand.setName("draw");
            
            MoveCommand moveCommand=new MoveCommand();
            moveCommand.setName("move");
            
            createCommand.setNext(drawCommand);
            drawCommand.setNext(moveCommand);
            
            return createCommand.execute(commands);
        }
    }
    

}

Test class:

public class ChainOfResponsibilityTest {

    @Test
    public void test() {
        ChainOfResponsibility chainOfResponsibility=new ChainOfResponsibility();
        ChainOfResponsibility.Client client=chainOfResponsibility. new Client();
        
        String result=client.execute("move, create");
        assertEquals("create..move", result);
        
    }

}

2. Command

  Actors: 
  1. executor- interface which have to be implemented by "command" object
  2. command - implementation of executor interface 
  3. receiver - "helper" object which used by command object
  Goal: implementation of "handler": in Java we can not pass function as parameter to another function, but be can pass command object and execute such a function on it.

Main class:




public class Command {

    public interface Executor {
        String execute();
    }
    
    public class Receiver {
        public String draw() {
            return "draw";
        }
        public String erase() {
            return "erase";
        }
    }
    
    public abstract class AbstractCommand implements Executor {
        protected Receiver receiver=new Receiver();
    } 
    
    public class DrawCommand extends AbstractCommand {
        
        @Override
        public String execute() {
            return receiver.draw();
        }
        
    }
    public class EraseCommand extends AbstractCommand {

        @Override
        public String execute() {
            return receiver.erase();
        }       
    }
    
    public class Client {
        public String doSomeAction(List<Executor> commands) {
            StringBuilder result=new StringBuilder();
            
            for (Executor eachCommand:commands) {
                result.append(eachCommand.execute()+".");
            }
            
            return result.toString();
        }
    }
    
}

Test class:

public class CommandTest {

    @Test
    public void test() {
        Command command =new Command();
        Command.DrawCommand draw=command. new DrawCommand();
        Command.EraseCommand erase=command. new EraseCommand();
        
        List<Command.Executor> commandList=new ArrayList<Command.Executor>();
        commandList.add(draw);
        commandList.add(draw);
        commandList.add(erase);
        
        Command.Client client=command. new Client();
        assertEquals("draw.draw.erase.", client.doSomeAction(commandList));
        
        
    }

}

3. Interpretator

Actors:
1. custom command language
2. expression written on this language
3. interpretator class which can interpret expression oin proper way and calculate it
Goal: calculating expression

Main class:
           

public class Interpretator {
    
    interface Operator {
        int calculate(int argument1, int argument2);
    }
    
    class PlusOperator implements Operator {
        
        @Override
        public int calculate(int argument1, int argument2) {            
            return argument1+argument2;
        }
        
    }
    
    class MinusOperator implements Operator {
        
        @Override
        public int calculate(int argument1, int argument2) {            
            return argument1-argument2;
        }
        
    }
    
    class Context {
        
        Map<String, Operator> operatorMap;
        
        public Context(Map<String, Operator> operatorMap) {
            if (operatorMap==null) {
                throw new RuntimeException("OperatorMap can not be null.");
            }
            this.operatorMap=operatorMap;   
        }
        
        
        public int getNearestOperatorPosition(String expression, int position) {
            int result=-1;
            for (String operator:operatorMap.keySet()) {
                int currentOperatorPosition=expression.indexOf(operator, position);
                if (result==-1 || (currentOperatorPosition!=-1 && currentOperatorPosition<result) ) { 
                    result=currentOperatorPosition;         
                }
            }
            return result;
        }
        
        public int getNearestOperandEnd(String expression, int position) {
            int operandEnd=-1;
            int nextOperatorPosition=getNearestOperatorPosition(expression, position);
            if (nextOperatorPosition==-1){
                operandEnd=expression.length();
            } else {
                operandEnd=nextOperatorPosition;
            }
            return operandEnd;
        }
        
        public int calculate(String expression) {
            if (expression==null || expression.length()==0) {
                return 0;
            }
                    
            int position=getNearestOperandEnd(expression, 0);
            String operandStringValue=expression.substring(0, position);
            int result=Integer.parseInt(operandStringValue);
            //position++;
            while (position<expression.length()) {
                String operator=expression.substring(position, position+1);
                Operator e=operatorMap.get(operator);               
                position++;
                int operandEnd=getNearestOperandEnd(expression, position);
                operandStringValue=expression.substring(position, operandEnd);
                int operand=Integer.parseInt(operandStringValue);
                result=e.calculate(result, operand);
                position=operandEnd;
            }
            
            return result;
        }
    }

}

Test class:

public class InterpretatorTest {
    
    Interpretator interpretator=new Interpretator();
    Interpretator.PlusOperator plusOperator=interpretator. new PlusOperator();
    Interpretator.MinusOperator minusOperator=interpretator. new MinusOperator();
    Interpretator.Context context;
    
    @Before
    public void init() {
        Map<String, Operator> operatorMap=new HashMap<String, Operator>();
        operatorMap.put("+", plusOperator);
        operatorMap.put("-", minusOperator);
        context=interpretator. new Context(operatorMap);
    }

    @Test
    public void getNearestOperatorPositionTest() {
        String expression="0123+34";
        int result=context.getNearestOperatorPosition(expression, 0);
        assertEquals(4, result);
        expression="012345-34";
        result=context.getNearestOperatorPosition(expression, 0);
        assertEquals(6, result);
    }
    
    @Test
    public void getNearestOperandEndTest() {
        String expression="0123+56";
        int result=context.getNearestOperandEnd(expression, 0);
        assertEquals(4, result);
        expression="0123+56";
        result=context.getNearestOperandEnd(expression, 5);
        assertEquals(7, result);
    }   
    
    @Test
    public void mainTestWithTraditionalOperators() {
            
        String expression="0123+56+8";
        int result=context.calculate(expression);
        assertEquals(123+56+8, result);
        
        expression="12+34-56";
        result=context.calculate(expression);
        assertEquals(12+34-56, result);
    }
    
    @Test
    public void mainTestWithExperimentalOperators() {
        Map<String, Operator> operatorMap=new HashMap<String, Operator>();
        operatorMap.put("P", plusOperator);
        operatorMap.put("M", minusOperator);
        context=interpretator. new Context(operatorMap);
        
        
        String expression="2P3M1";
        int result=context.calculate(expression);
        assertEquals(4, result);
        
    }   

}

4. Iterator

Actors:
   1. iterator interface which describes it operation list
   2. iterator object which implements interface
   3. iterable object - object which has method for returning it iterator
Goal: iterate through  array of elements using iterator object

Main class:

public class Iterator {

    interface SimpleIterator<T> {
        boolean hasNext();
        T getNext();
    } 
        
    class ArrayIterator<T> implements SimpleIterator<T> {
        T[] array;
        int position=-1;
        
        public ArrayIterator(T[] array) {
            this.array=array;
        }

        @Override
        public boolean hasNext() {
            if (position<array.length-1) {
                return true;
            }
            return false;
        }

        @Override
        public T getNext() {
            position++;
            return array[position];         
        }
        
    }
    
    interface Iterable<T>{
        SimpleIterator<T> getIterator();
    }
    
    class ArrayIterable<T> implements Iterable<T> {
        private T[] array;
        
        public ArrayIterable(T[] array) {
            this.array=array;
        }

        @Override
        public SimpleIterator<T> getIterator() {
            return new ArrayIterator<T>(array);
        }       
    }
        
    
}

Test class:

public class IteratorTest {

    @Test
    public void test() {
        String[] array=new String[]{"a", "b", "c"};
        Iterator iterator=new Iterator();
        Iterator.ArrayIterable<String> arrayIterable=iterator. new ArrayIterable<String>(array);
        Iterator.SimpleIterator<String> arrayIterator=arrayIterable.getIterator();
        StringBuilder result=new StringBuilder();
        while (arrayIterator.hasNext()) {
            String element=arrayIterator.getNext();
            result.append(element);
        }       
        assertEquals("abc", result.toString());             
        
    }

}

5. Mediator

Actors:
1. components
2. client
3. mediator
Goal: add some new functionality by combining existing. 
   client communicate with mediator but not with components.  
   mediator - HUB of components communication.

Main class:

public class Mediator {
    
    public class Drawer {
        public String drawShape(String shape) {
            return "drawing:"+shape;
        }
    }
    
    public class Mover {
        public String moveShape(String shape) {
            return "moving:"+shape;
        }
    }
    
    public class ShapeMediator {
        Drawer drawer=new Drawer();
        Mover mover=new Mover();
        
        public String drawAndMove(String shape) {
            return drawer.drawShape(shape)+"."+mover.moveShape(shape);
        }
    }

}

Test class:

public class MediatorTest {

    @Test
    public void test() {
        Mediator mediator=new Mediator();
        Mediator.ShapeMediator shapeMediator=mediator. new ShapeMediator();
        String result=shapeMediator.drawAndMove("square");
        assertEquals("drawing:square.moving:square", result);
    }

}

6. Memento

Actors: 
 1. memento class
 2. client
 Goal: memento object saves it state on every change. 
   so, we can get it state, for every step we want.


Main class:


public class Memento {

    public class Shape {
        private int x;
        private int y;

        public int getX() {
            return x;
        }

        public int getY() {
            return y;
        }

        public void moveTo(int x, int y) {
            this.x=x;
            this.y=y;
        }

    }

    public class ShapeMemento {
        private List<Shape> history=new ArrayList<Shape>();

        public void save(Shape shape) {
            Shape historyShape=new Shape();
            historyShape.moveTo(shape.getX(), shape.getY());
            history.add(historyShape);
        }

        public Shape getShapeForStep(int index) {
            Shape result=history.get(index);
            return result;
        }
    }

}


Test class:

public class MementoTest {

    @Test
    public void mementoTest(){
        Memento memento=new Memento();
        Memento.Shape shape=memento. new Shape();
        Memento.ShapeMemento shapeMemento=memento. new ShapeMemento();
        shape.moveTo(0,0);
        shapeMemento.save(shape);
        shape.moveTo(1,1);
        shapeMemento.save(shape);

        shape=shapeMemento.getShapeForStep(0);
        Assert.assertEquals(0, shape.getX());
        Assert.assertEquals(0, shape.getY());

        shape=shapeMemento.getShapeForStep(1);
        Assert.assertEquals(1, shape.getX());
        Assert.assertEquals(1, shape.getY());

    }
}

Sunday, August 31, 2014

Structural design patterns in Java

Simple examples of using structural design patterns in Java.
List of them from wikipedia:
Examples of Structural Patterns include:
  • Adapter pattern: 'adapts' one interface for a class into one that a client expects
    • Adapter pipeline: Use multiple adapters for debugging purposes.[1]
    • Retrofit Interface Pattern:[2][3] An adapter used as a new interface for multiple classes at the same time.
  • Bridge pattern: decouple an abstraction from its implementation so that the two can vary independently
    • Tombstone: An intermediate "lookup" object contains the real location of an object.[4]
  • Composite pattern: a tree structure of objects where every object has the same interface
  • Decorator pattern: add additional functionality to a class at runtime where subclassing would result in an exponential rise of new classes
  • Facade pattern: create a simplified interface of an existing interface to ease usage for common tasks
  • Flyweight pattern: a high quantity of objects share a common properties object to save space
  • Proxy pattern: a class functioning as an interface to another thing

1. Adapter pattern.

 Actors:
  1. "convenient" interface
  2. adapter class which adapt "non-convenient" classes to match "convenient" interface
  Goal: using methods of interface on class which doesn't implements that interface using adaptor class.

Main class:

public class Adaptor {
    
    public interface Movable {
        String move();
    }
    
    public class Shape {
        private String name;
        
        public Shape(String name) {
            this.name=name;
        }
        
        public String relocate() {
            return "shape "+name+" is relocated";
        }
    }
    
    public class ShapeToMovableAdaptor implements Movable {
        
        private Shape shape;
        
        public ShapeToMovableAdaptor(Shape shape) {
            this.shape=shape;
        }

        @Override
        public String move() {          
            return shape.relocate();
        }   
    }
}



Test class:

public class AdaptorTest {
    
    @Test
    public void test() {
        Adaptor adaptor=new Adaptor();
        
        Adaptor.Shape shape=adaptor. new Shape("circle");
        
        Adaptor.Movable shapeAdaptor=adaptor. new ShapeToMovableAdaptor(shape);
        
        String result=shapeAdaptor.move();
        
        Assert.assertEquals("shape circle is relocated", result);
    }

}


2. Bridge

  Actors:
    1. Implementation
    2. Abstraction - which depends(aggregate) on Implementation (for instance, Implementation set in constructor)
    3. Concrete classes which extends Abstraction
  Goal: implementation separated from abstraction
Main class:


public class Bridge {
    
    interface Implementation {
        String move();
    }
    
    class FastImplementation implements Implementation {
        @Override
        public String move() {
            return "fast";
        }       
    }
    
    class SlowImplementation implements Implementation {
        @Override
        public String move() {
            return "slow";
        }       
    }   
    
    
    public abstract class Abstraction{
        
        Implementation implementation;
        
        public Abstraction(Implementation implementation) {
            this.implementation=implementation;
        }
        
        public String rellocate() {
            return implementation.move() +" rellocation";
        }
        
    }
    
    public class ConcreteSlowClass extends Abstraction {

        public ConcreteSlowClass() {
            super(new SlowImplementation());
        }
        
    }
    
    public class ConcreteFastClass extends Abstraction {

        public ConcreteFastClass() {
            super(new FastImplementation());
        }
        
    }   
}

Test class:

public class BridgeTest {

    @Test
    public void test() {
        Bridge bridge=new Bridge();
        
        Bridge.ConcreteFastClass fast=bridge. new ConcreteFastClass();
        assertEquals("fast rellocation", fast.rellocate());
        
        
        Bridge.ConcreteSlowClass slow=bridge. new ConcreteSlowClass();
        assertEquals("slow rellocation", slow.rellocate());
    }

}

3. Composite

Actors:
  1. interface
  2. simple object which implements interface
  3. complex object(contain set of simple objects) with implements interface
  Goal:
  Do some logic with set(array) of objects like one single object
Main class:


public class Composite {

    public interface drawable {
        String draw();
    }

    public class SimpleObject implements drawable {

        String name;

        @Override
        public String draw() {
            return "drawing " + name;
        }

        public SimpleObject(String name) {
            this.name = name;
        }

    }

    public class CompositeObject implements drawable {

        List<Composite.SimpleObject> objects=new ArrayList<Composite.SimpleObject>();

        public void addObject(Composite.SimpleObject object) {
            objects.add(object);
        }

        @Override
        public String draw() {
            StringBuilder result = new StringBuilder();

            for (Composite.SimpleObject object : objects) {
                result.append(object.draw() + ".");
            }

            return result.toString();
        }

Test class:

    }

}
public class CompositeTest {

    @Test
    public void test() {
        Composite composite=new Composite();
        
        Composite.SimpleObject simple1=composite. new SimpleObject("first");
        assertEquals("drawing first", simple1.draw());
        
        Composite.SimpleObject simple2=composite. new SimpleObject("second");
        
        Composite.CompositeObject complex=composite. new CompositeObject();
        complex.addObject(simple1);
        complex.addObject(simple2);
                
        assertEquals("drawing first.drawing second.", complex.draw());
                
    }

}

4. Decorator

  Actors:
  1. original class
  2. decorator class which wrap original class
  Goal: extend functionality of original class
Main class:


public class Decorator {
    
    public static class Shape {
        public String draw() {
            return "shape";
        }
    }
    
    public static class RedDecorator  {
        private Shape shape;

        public RedDecorator(Shape shape) {
            this.shape=shape;
        }

        public String drawRed() {
            return shape.draw()+" is red";
            
        }       
    }
    
    public static class BigDecorator {
        private RedDecorator redDecorator;

        public BigDecorator(RedDecorator redDecorator) {
            this.redDecorator=redDecorator;
        }

        public String drawBig() {
            return redDecorator.drawRed()+" and big";
            
        }       
    }   

}

Test class:

public class DecoratorTest {

    @Test
    public void test() {

        String result=new Decorator.BigDecorator(new Decorator.RedDecorator(new Decorator.Shape())).drawBig();


        assertEquals("shape is red and big", result);
        
    }

}

5. Facade

Actors:
  1. set of classes  (library)
  2. facade class for managing them
  Goal: interface for library: one class which manage other classes

Main class:

public class Facade {
    
    public interface Drawable {
        public String draw();
    }
    
    public class Square implements Drawable {

        @Override
        public String draw() {          
            return "square.";
        }
        
    }
    
    public class Circle implements Drawable {

        @Override
        public String draw() {          
            return "circle.";
        }
        
    }
    
    
    public class ComplexDrawingFacade {
                
        public String drawComplexObject() {
            Square square1=new Square();
            Square square2=new Square();
            Circle circle=new Circle();
            
            String result=square1.draw()+circle.draw()+square2.draw();
            
            return result;      
        }
        
    }

}

Test class:

public class FacadeTest {

    @Test
    public void test() {
        Facade facade=new Facade();
        
        Facade.ComplexDrawingFacade compleDrawingFacade=facade. new ComplexDrawingFacade();
        assertEquals("square.circle.square.", compleDrawingFacade.drawComplexObject());
    }

}

6. FlyWeight

Actors:
 1. set of objects
 2. flyweight(cache) object: contains list of created objects
 Goal: using object cache(for memory minimizing) and object sharing instead of new object creation


public class FlyWeight {
    
    public static abstract class AbstractShape {
        public abstract String draw();
    }
    
    public static class Shape extends AbstractShape {

        @Override
        public String draw() {
            return "shape";
        }       
    }
    
    public static class Circle extends AbstractShape {

        @Override
        public String draw() {
            return "circle";
        }       
    }
    
    public class FlyWeightFactory {
        HashMap<String, AbstractShape> cache=new HashMap<String, AbstractShape>(); 
        public AbstractShape lookUp(Class<?> cl) throws InstantiationException, IllegalAccessException {
            String className=cl.getCanonicalName();
            if (!cache.containsKey(className)) {
                try {
                    Object o=cl.newInstance();
                } catch(Exception e) {
                    e.printStackTrace();
                }
                AbstractShape shape=(AbstractShape)cl.newInstance();
                
                cache.put(className, shape);
            }           
            return cache.get(className);
        }
    }

}

Test class:

public class FlyWeightTest {

    @Test
    public void test() throws InstantiationException, IllegalAccessException {
        
        FlyWeight flyWeight=new FlyWeight();
        FlyWeight.FlyWeightFactory factory=flyWeight. new FlyWeightFactory();
        
        
        FlyWeight.AbstractShape circle=factory.lookUp(FlyWeight.Circle.class);
        FlyWeight.AbstractShape shape=factory.lookUp(FlyWeight.Shape.class);
        
        assertEquals("shape", shape.draw());
        assertEquals("circle", circle.draw());
        
    }

}

7. Proxy

Actors:
  1. remote object
  2. local proxy class which has the same interface as remote object
  3. local client, which works with proxy as like it is remote object
  Goal : make client independent of remote object and connection. 
  Also proxy object can add some addition functionality, checking and other stuff.

Main class:

public class Proxy {
    
    interface Drawable {
        String draw();
    }
    
    public class RealImplementation implements Drawable {

        @Override
        public String draw() {
            return "real draw";
        }
        
    }
    
    public class ProxyImplementation extends RealImplementation {
        
        RealImplementation realImplementation=new RealImplementation();

        @Override
        public String draw() {
            // do some logic
            return realImplementation.draw();
            // do some logic
        }
        
    }

}

Test class:

public class ProxyTest {

    @Test
    public void test() {
        Proxy proxy=new Proxy();
        Proxy.RealImplementation remoteObject=proxy. new ProxyImplementation();
        assertEquals("real draw", remoteObject.draw());
        
    }

}



Creational design patterns in Java

In this post, I'm going to show samples of using creational design patterns in Java.
List of them from wikipedia:
  • Abstract factory pattern, which provides an interface for creating related or dependent objects without specifying the objects' concrete classes.[3]
  • Builder pattern, which separates the construction of a complex object from its representation so that the same construction process can create different representation.
  • Factory method pattern, which allows a class to defer instantiation to subclasses.[4]
  • Prototype pattern, which specifies the kind of object to create using a prototypical instance, and creates new objects by cloning this prototype.
  • Singleton pattern, which ensures that a class only has one instance, and provides a global point of access to it.[5]
Let's consider them closely. 

1. Abstract factory.

Actors: 
 1.abstract factory - interface which defines factory which can be returned.
 2.concrete factory:  concrete class which implements abstract factory and returns implementations of factories.  
Goal: create in one step different objects using different creation classes(factories).
Main class:
public class AbstractFactory {
    
    public static abstract class AbstractShapeFactory {
        public abstract RedShapeFactory getRedShapeFactory();
        public abstract BlackShapeFactory getBlackShapeFactory();
    }
    
    public static abstract class Drawable {
        protected String pattern;
        public Drawable(String pattern) {
            this.pattern=pattern;
        }
        public abstract String createShape(String pattern);
    }
    
    public static class RedShapeFactory extends Drawable {

        public RedShapeFactory(String pattern) {
            super(pattern);
        }

        @Override
        public String createShape(String pattern) {
            return "red "+pattern;          
        }       
    }
    
    public static class BlackShapeFactory extends Drawable {
        public BlackShapeFactory(String pattern) {
            super(pattern);
        }

        @Override
        public String createShape(String pattern) {
            return "black "+pattern;            
        }       
    }
    
    public static class ShapeFactory extends AbstractShapeFactory {
        private final String pattern;
        
        public ShapeFactory(String pattern) {
            this.pattern=pattern;
        }

        @Override
        public RedShapeFactory getRedShapeFactory() {
            return new RedShapeFactory(pattern);
        }

        @Override
        public BlackShapeFactory getBlackShapeFactory() {
            return new BlackShapeFactory(pattern);
        }
        
    }

}


Test class:


import org.junit.Before;
import org.junit.Test;

public class AbstractFactoryTest {
    
    AbstractFactory.ShapeFactory factory;
    String pattern;
    
    @Before
    public void init() {
        pattern="square";
    }

    @Test
    public void blackFactoryTest() {
        factory=new AbstractFactory.ShapeFactory(pattern);
        String result=factory.getBlackShapeFactory().createShape(pattern);
        assertEquals("black square", result);
    }

    @Test
    public void redFactoryTest() {
        factory=new AbstractFactory.ShapeFactory(pattern);
        String result=factory.getRedShapeFactory().createShape(pattern);
        assertEquals("red square", result);
    }
}

2. Factory method

May be the simplest matters: very often developers starts with this pattern and later migrate to more complex solutions.  
Actors: 
1.factory method class with different methods for creation different classes
Goal: 
create in one step different objects using different functions.
Main class:

public class FactoryMethod {
    
    public String createRedSquareStringObject() {
        return "red square";
    }
    
    public String createBlackSquareStringObject() {
        return "black square";
    }

}

Test class:

public class FactoryMethodTest {
    
    private FactoryMethod factory=new FactoryMethod();
    
    @Test
    public void readSquareTest() {
        String shape=factory.createRedSquareStringObject();
        Assert.assertEquals("red square", shape);
    }
    
    @Test
    public void blackSquareTest() {
        String shape=factory.createBlackSquareStringObject();
        Assert.assertEquals("black square", shape);
    }

}

3. Builder

Actors: builder class with methods for adding components to the created object.
Goal: create different objects(with different components) in few steps.
Main class:

public class Builder {
    
    public void addFundament(StringBuilder object) {
        object.append("fundament ");
    } 
    
    public void addFloor(StringBuilder object) {
        object.append("floor ");
    }
    
    public void addMansarda(StringBuilder object) {
        object.append("mansarda");
    }   
    
    public void addRoof(StringBuilder object) {
        object.append("roof");
    }
 
}

Test class:

public class BuilderTest {
    
    private Builder builder=new Builder(); 
    
    @Test
    public void oneFlootBuildingWithRoofTest() {
        StringBuilder building=new StringBuilder();
        
        builder.addFundament(building);
        builder.addFloor(building);
        builder.addRoof(building);
        
        Assert.assertEquals("fundament floor roof", building.toString());
         
    }
    
    @Test
    public void threeFlootBuildingWithMansardaTest() {
        StringBuilder building=new StringBuilder();
        
        builder.addFundament(building);
        builder.addFloor(building);
        builder.addFloor(building);
        builder.addFloor(building);
        builder.addMansarda(building);
        
        Assert.assertEquals("fundament floor floor floor mansarda", building.toString());
         
    }   

}

4.Singleton

Actors: class with static instance 
Goal: only one instance of object can be created and  used by other objects.
Main class:


public enum Singleton {
        INSTANCE;
        
        public String data;
        
}

Test class:

public class SingletonTest {
    
    @Test
    public void test() {
        Singleton s1=Singleton.INSTANCE;
        Singleton s2=Singleton.INSTANCE;
        s1.data="Hello world!";
        Assert.assertEquals(s1.data, s2.data);      
    }
}

5.Prototype

Actors: class which implements Clonable interface
 Goal: sometimes when object has a lot of properties, it's easier to clone object than execute setXXX a lot of times.
Main class:

public class Prototype {
    
    public class ComplexObject implements Cloneable{
                
        private String name;
        private String description;
        private String department;
        
        public ComplexObject(String name, String description, String department) {
            super();
            this.name = name;
            this.description = description;
            this.department = department;
        }
        
        public ComplexObject clone() throws CloneNotSupportedException {
            return (ComplexObject)super.clone();
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getDescription() {
            return description;
        }

        public void setDescription(String description) {
            this.description = description;
        }

        public String getDepartent() {
            return department;
        }

        public void setDepartent(String departent) {
            this.department = departent;
        }
    }
}

Test class:





public class PrototypeTest {
    
    @Test
    public void test() throws CloneNotSupportedException {
        Prototype prototype=new Prototype();
        
        Prototype.ComplexObject complexObject1= prototype. new ComplexObject("name", "description", "departent");
        Prototype.ComplexObject complexObject2=complexObject1.clone();
        
        Assert.assertEquals(complexObject1.getName(), complexObject2.getName());
        Assert.assertEquals(complexObject1.getDescription(), complexObject2.getDescription());
        Assert.assertEquals(complexObject1.getDepartent(), complexObject2.getDepartent());
        
    }

}