복습
프로토타입 패턴(Prototype Pattern) 본문
프로토타입 패턴이란?
- 객체를 생성하는 데 비용이 많이 들고, 비슷한 객체가 이미 있는 경우에 사용되는 생성 패턴
- Original 객체를 새로운 객체에 복사하여 필요에 따라 수정하는 메커니즘 제공
- Java의 경우 clone()을 사용하여 객체를 복사
객체를 복사할 때의 문제
- 객체 복사본 생성
- 같은 클래스의 객체 생성
- 원본 객체의 필드를 모두 탐색하여 복사
- 문제점
- 객체의 필드가 일부 비공개일 수 있음
- 객체의 복사본을 생성하려면 해당 객체의 클래스를 알아야 하므로 해당 클래스에 의존하게 됨
- 인터페이스를 사용할 때 구현 클래스는 알 수 없음
프로토타입 패턴을 통한 해결
- 복제되는 객체들에 복제 프로세스를 위임
- 복제를 지원하는 모든 객체에 대한 공통 인터페이스 선언
- clone 메서드를 통해 현재 클래스의 객체를 만든 후 이전 객체의 모든 필드 값을 새 객체로 전달
프로토타입 패턴 구조
- 프로토타입(prototype)
- 인터페이스로 복제 메서드인 clone()을 선언한다.
- 구상 프로토타입(ConcretePrototype)
- 복제 메서드를 구현하는데 원본 객체를 복사하는 것 이외에 복제 프로세스와 관련된 예외처리도 가능
- 클라이언트
- 프로토타입 인터페이스를 따르는 모든 객체의 복사본을 생성
장점
- 구상 클래스에 의존하지 않고 복제할 수 있음
- 반복되는 초기화 코드 없이 프로토타입을 복제하여 객체를 생성할 수 있음
- 복잡한 객체들을 쉽게 생성할 수 있음
단점
- 순환 참조가 있는 복잡한 객체들을 복제할 때 까다로움
프로토타입 패턴 구현
public abstract class Shape {
public int x;
public int y;
public String color;
public Shape() {
}
public Shape(Shape target) {
if (target != null) {
this.x = target.x;
this.y = target.y;
this.color = target.color;
}
}
public abstract Shape clone();
@Override
public boolean equals(Object object2) {
if (!(object2 instanceof Shape)) return false;
Shape shape2 = (Shape) object2;
return shape2.x == x && shape2.y == y && Objects.equals(shape2.color, color);
}
}
-------------------------------------------------------------------------------
public class Circle extends Shape {
public int radius;
public Circle() {
}
public Circle(Circle target) {
super(target);
if (target != null) {
this.radius = target.radius;
}
}
@Override
public Shape clone() {
return new Circle(this);
}
@Override
public boolean equals(Object object2) {
if (!(object2 instanceof Circle) || !super.equals(object2)) return false;
Circle shape2 = (Circle) object2;
return shape2.radius == radius;
}
}
-------------------------------------------------------------------------------
public class Rectangle extends Shape {
public int width;
public int height;
public Rectangle() {
}
public Rectangle(Rectangle target) {
super(target);
if (target != null) {
this.width = target.width;
this.height = target.height;
}
}
@Override
public Shape clone() {
return new Rectangle(this);
}
@Override
public boolean equals(Object object2) {
if (!(object2 instanceof Circle) || !super.equals(object2)) return false;
Circle shape2 = (Circle) object2;
return shape2.radius == radius;
}
}
----------------------------------------------------------------------
public static void main(String[] args) {
List<Shape> shapes = new ArrayList<>();
List<Shape> shapesCopy = new ArrayList<>();
Circle circle = new Circle();
circle.x = 10;
circle.y = 20;
circle.radius = 15;
circle.color = "red";
shapes.add(circle);
Circle anotherCircle = (Circle) circle.clone();
shapes.add(anotherCircle);
}
- 추상 메서드 clone()이 있는 추상 클래스 Shape
- Shape를 상속받은 Circle과 Rectangle
- Circle이나 Rectangle을 복사할 때 따로 객체를 생성해서 멤버변수를 설정할 필요없이 clone 메서드로 쉽게 복제
의문점...
- 어떤 경우에 유용하게 잘 사용할 수 있을지 모르겟음..
참고
https://refactoring.guru/ko/design-patterns/prototype
프로토타입 패턴
/ 디자인 패턴들 / 생성 패턴 프로토타입 패턴 다음 이름으로도 불립니다: 클론, Prototype 의도 프로토타입은 코드를 그들의 클래스들에 의존시키지 않고 기존 객체들을 복사할 수 있도록 하는 생
refactoring.guru
'CS > Design Pattern' 카테고리의 다른 글
커맨드 패턴(Command Pattern) (0) | 2023.04.05 |
---|---|
노출 모듈 패턴(Revealing Module Pattern) (0) | 2023.04.05 |
옵저버 패턴(Observer Pattern) (0) | 2023.03.29 |