Design Patterns - Prototype Pattern
프로토타입 패턴은 퍼포먼스를 염두하면서 중복된 객체를 생성하는 것을 가리킨다. 이 디자인 패턴의 형태는 이 패턴이 객체를 생성하는 가장 좋은 방법 중 하나를 제공하기 때문에 생성적 패턴에 포함된다.
이 패턴은 현재 객체의 클론을 생성하는 것을 말하는 prototype interface를 구현하는 것을 필요로 한다. 이 패턴은 객체의 생성이 직접적으로 비쌀 때 사용되어 진다. 예를 들면, 어떤 객체는 비싼 database 연산 후 생성되어진다. 우리는 그 객체를 cache할 수 있고, 다음 요청에서 이것의 클론을 반환한다. 그리고 그것으로 database를 갱신한다 그러면 필요한 때 database호출이 감소한다.(음..정확한 해석이 안된다..ㅠ.ㅠ)
Implementation
Shape 추상 클래스와 Shape클래스를 확장하는 구체적인 클래서를 생성할 것이다. ShapeCache 클래스는 Hashtable에 shape 객체를 저장하는 다음단계로써 정의되어지고 요청되어질 때 거것의 클론을 반환한다.
PrototypePatternDemo demo 클래스는 shape객체를 얻기위해 SahpeCache클래스를 사용할 것이다.
Step 1
Clonable interface를 구현하는 추상객체를 생성한다.
Shape.java
public abstract class Shape implements Cloneable { private String id; protected String type; abstract void draw(); public String getType(){ return type; } public String getId() { return id; } public void setId(String id) { this.id = id; } public Object clone() { Object clone = null; try { clone = super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return clone; } }
Step 2
위 클래스를 확장하는 구체적 클래스를 생성한다.
Rectangle.java
public class Rectangle extends Shape { public Rectangle(){ type = "Rectangle"; } @Override public void draw() { System.out.println("Inside Rectangle::draw() method."); } }
Square.java
public class Square extends Shape { public Square(){ type = "Square"; } @Override public void draw() { System.out.println("Inside Square::draw() method."); } }
Circle.java
public class Circle extends Shape { public Circle(){ type = "Circle"; } @Override public void draw() { System.out.println("Inside Circle::draw() method."); } }
Step 3
데이터베이스로부터 구체적인 클래스를 얻기고 그것을 Hashtable에 저장하는 클래스를 생성한다.
ShapeCache.java
import java.util.Hashtable; public class ShapeCache { private static Hashtable<String, Shape> shapeMap = new Hashtable<String, Shape>(); public static Shape getShape(String shapeId) { Shape cachedShape = shapeMap.get(shapeId); return (Shape) cachedShape.clone(); } // for each shape run database query and create shape // shapeMap.put(shapeKey, shape); // for example, we are adding three shapes public static void loadCache() { Circle circle = new Circle(); circle.setId("1"); shapeMap.put(circle.getId(),circle); Square square = new Square(); square.setId("2"); shapeMap.put(square.getId(),square); Rectangle rectangle = new Rectangle(); rectangle.setId("3"); shapeMap.put(rectangle.getId(), rectangle); } }
Step 4
PrototypepatternDemo는 Hashtable에 저장된 shape의 클론을 얻기위해 ShapeCache클래스를 사용한다.
PrototypePatternDemo.java
public class PrototypePatternDemo { public static void main(String[] args) { ShapeCache.loadCache(); Shape clonedShape = (Shape) ShapeCache.getShape("1"); System.out.println("Shape : " + clonedShape.getType()); Shape clonedShape2 = (Shape) ShapeCache.getShape("2"); System.out.println("Shape : " + clonedShape2.getType()); Shape clonedShape3 = (Shape) ShapeCache.getShape("3"); System.out.println("Shape : " + clonedShape3.getType()); } }
Step 5
결과를 확인한다.
Shape : Circle Shape : Square Shape : Rectangle