*Prototype Pattern
Prototype : 실행 중에 생성된 객체로 다른 객체를 생성하는 패턴. 'new class' 사용해 생성하는 게 아니고 이미 생성된 객체를 통해 독립된 또 다른 객체를 생성함.
Prototype으로 만든 객체의 상태를 변경해도 원본 객체의 상태는 변경되지 않음.
Prototype: 객체로부터 또 다른 새로운 객체를 생성하는 API 가지고 있음
Shape : 도형에 대한 API
Point, Line, Grpup : 도형을 구체적으로 구현, Prototype, Shape를 구현.
Group : Shape 인터페이스와 호환되는 여러 개의 객체를 이용해 새로운 도형을 생성 가능.

public interface Prototype {
Object copy();
}
public interface Shape {
String draw(); // 도형을 표현하는 문자열을 반환하는 매서드
void moveOffset(int dx, int dy); // 도형을 이동하는 메서드
}
public class Point implement Shape, Prototype {
private int x;
private int y;
public Point setX(int x) {
this.x = x;
return this;
}
public Point setY(int y) {
this.y = y;
return this;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
@Override
public Object copy() {
Point newPoint = new Point();
newPoint.x = this.x;
newPoint.y = this.y;
return newPoint;
}
@Override
public String draw() {
return "(" + x + " " + y + ")";
}
@Override
public void moveOffset(int dx, int dy) {
this.x += dx;
this.y += dy;
}
}
public class Line implements Shape, Prototype {
private Point startPt;
private Point endPt;
public Line setStartPoint(Point pt) {
this.startPt = pt;
return this;
}
public Line setEndPoint(Point pt) {
this.endtPt = pt;
return this;
}
public Point getStartPoint() {
return startPt;
}
public Point getEndPoint() {
return endPt;
}
@Override
public Object copy() {
Line newLine = newLine();
newLine.startPt = (Point)startPt.copy();
newLine.endPt = (Point)endPt.copy();
return newLine;
}
@Override
public String draw() {
return "LINE(" + startPt.draw() + "," + endPt.draw() + ")";
}
@Override
public void moveOffset(int dx, int dy) {
startPt.moveOffset(dx, dy);
endPt.moveOffset(dx, dy);
}
}
public class Group implements Shape, Prototype {
private ArrayList<Shape> shapeList = new ArrayList<>();
private String name;
public Group(String name) {
this.name = name;
}
Group addShape(Shape shape) {
shapeList.add(shape);
return this;
}
@Override
public Object copy() {
Group newGroup = new Group(name);
Iterator<Shape> iter = shapeList.iterator();
while(iter.hasNext()) {
Prototype shape = (Prototype)iter.next();
newGroup.shapeList.add((Shape)shape.copy());
}
return newGroup;
}
@Override
public String draw() {
StringBuffer result = new StringBuffer(name);
result.append("(");
Iterator<Shape> iter = shapeList.iterator();
while(iter.hasNext()) {
Shape shape = iter.next();
result.append(shape.draw());
if(iter.hasNext()) {
result.append(" ");
}
}
result.append(")");
return result.toString();
}
@Override
public void moveOffset(int dx, int dy) {
Iterator<Shape> iter = shapeList.iterator();
while(iter.hasNext()) {
Shape shape = iter.next();
shape.moveOffset(dx, dy);
}
}
}
실행 중 만든 객체를 통해 새로운 객체를 생성하는 패턴
이때 원본의 객체와 복사본의 객체는 완전 독립이어서 서로 영향을 주지 않음.
기존의 클래스를 조합해 새로운 개념의 객체를 생성하는 상황에서 Prototype 패턴을 적용하면 좋다.
public static void main(String[] args) {
Point pt1 = new Point();
pt1.setX(0).setY(0);
Point pt2 = new Point();
pt2.setX(100).setY(0);
Lint line1 = new Line();
line1.setStartPoint(pt1).setEndPoint(pt2);
Line lineCopy = (Line)line1.copy();
Point pt3 = new Point();
pt3.setX(100).setY(100);
Point pt4 = new Point();
pt4.setX(0).setY(100);
Line line2 = new Line();
line2.setStartPoint(pt2).setEndPoint(pt3);
Line line3 = new Line();
line3.setStartPoint(pt3).setEndPoint(pt4);
Line line4 = new Line();
line4.setStartPoint(pt4).setEndPoint(pt1);
Group rect = new Group("RECT");
rect.addShape(line1).addShape(line2).addShape(line3).addShape(line4);
System.out.println(rect.draw());
Group cloneRect = (Group)rect.copy();
cloneRect.moveOffset(100,100);
}
'코딩 > Software Architecture' 카테고리의 다른 글
| [GoF Design Pattern] Flyweight (0) | 2022.12.04 |
|---|---|
| [GoF Design Pattern] Command (0) | 2022.12.04 |
| [GoF Design Pattern] Proxy (0) | 2022.12.02 |
| [GoF Design Pattern] Factory Method, Observer (0) | 2022.12.01 |
| [GoF Design Pattern] Singleton, Bridge, Template, Adapter (0) | 2022.11.26 |