prototype pattern
원형이 되는 인스턴스를 사용하여 생성할 객체의 종류를 명시하고, 이렇게 만든 견본을 복사해서 새로운 객체를 생성합니다.
object 생성이 높은 비용으로 수 많은 요청을 하는 경우, 또는 비슷한 object를 지속적으로 생성해야 할 때 유용하게 사용할 수 있다. prototype pattern은 본래의 object로 부터 새로운 object를 만들어내며(서로 다른 인스턴스), 각 객체에 따라 데이터 수정이 가능한 메커니즘을 제공
java의 clone()을 이용하기 때문에 생성하고자 하는 객체에 clone에 대한 Override를 요구합니다.
1. Shape 인터페이스 구현
- Cloneable을 상속받아서 clone을 오버라이딩 try catch을 통해서 익셉션을 바로 처리하도록 함
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;
}
@Override
protected Object clone() {
Object clone = null;
try {
clone = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return clone;
}
}
2. Shape를 상속받은 모형 구현
public class Circle extends Shape {
public Circle(){
type = "원";
}
@Override
public void draw() {
System.out.println("원을 그렸습니다.");
}
}
public class Rectangle extends Shape {
public Rectangle(){
type = "직사각형";
}
@Override
public void draw() {
System.out.println("직사각형을 그렸습니다.");
}
}
public class Square extends Shape {
public Square(){
type = "정사각형";
}
@Override
public void draw() {
System.out.println("정사각형을 그렸습니다.");
}
}
3.shapeCache를 구현
- 데이터를 쌓는 메서드와 cache에서 shape를 넘겨줄때 clone하여 리턴
import java.util.HashMap;
public class ShapeCache {
private static final HashMap<String, Shape> shapeMap = new HashMap<>();
public static Shape getShape(String shapeId) {
Shape cachedShape = shapeMap.get(shapeId);
// 클론한 값을 리턴
return (Shape) cachedShape.clone();
}
// Hashtable 데이터 load
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);
}
}
4. main()
- cache에 데이터를 load한 뒤 getShape를 통해서 clone한 Shape 가져옴.
public class PrototypePatternDemo {
public static void main(String[] args) {
ShapeCache.loadCache();
Shape clonedShape = ShapeCache.getCloneShape("1");
Shape noClonedShape = ShapeCache.getNoCloneShape("1");
System.out.println("Shape : " + clonedShape.getType());
System.out.println("Shape : " + noClonedShape.getType());
System.out.println(clonedShape.equals(noClonedShape));
System.out.println(clonedShape.hashCode());
System.out.println(noClonedShape.hashCode());
System.out.println();
Shape clonedShape2 = ShapeCache.getCloneShape("2");
Shape noClonedShape2 = ShapeCache.getNoCloneShape("2");
System.out.println("Shape : " + clonedShape2.getType());
System.out.println("Shape : " + noClonedShape2.getType());
System.out.println(clonedShape2.equals(noClonedShape2));
System.out.println(clonedShape2.hashCode());
System.out.println(noClonedShape2.hashCode());
System.out.println();
Shape clonedShape3 = ShapeCache.getCloneShape("3");
Shape noClonedShape3 = ShapeCache.getNoCloneShape("3");
System.out.println("Shape : " + clonedShape3.getType());
System.out.println("Shape : " + noClonedShape3.getType());
System.out.println(clonedShape3.equals(noClonedShape3));
System.out.println(clonedShape3.hashCode());
System.out.println(noClonedShape3.hashCode());
}
}
5. 결과
- clone을 하면 동일하게 type값이 나오지만 equls나 hashcode를 사용하면 동일하지 않다고 나온는 것을 확인 할 수 있다. 즉 clone을 통해서 만든 값은 기존 값과 내용은 같으나 주소값이 다른 다른 객체이다. 이를 통해서 기존 값을 수정하면 안되지만 수정해야하는 로직을 처리해야할때 clone을 통해서 만들고 해당 값을 수정하도록 할 수 있다.
Shape : 원
Shape : 원
false
460141958
1163157884
Shape : 정사각형
Shape : 정사각형
false
1956725890
356573597
Shape : 직사각형
Shape : 직사각형
false
1735600054
21685669
'Design Pattern > 생성 패턴' 카테고리의 다른 글
Builder Pattern (0) | 2021.04.13 |
---|---|
Singleton Pattern (0) | 2021.04.12 |
Abstract Factory Pattern (0) | 2021.04.12 |
Factory Pattern (0) | 2021.04.12 |