복습

프로토타입 패턴(Prototype Pattern) 본문

CS/Design Pattern

프로토타입 패턴(Prototype Pattern)

ykm1256 2023. 11. 2. 17:17

프로토타입 패턴이란?

  • 객체를 생성하는 데 비용이 많이 들고, 비슷한 객체가 이미 있는 경우에 사용되는 생성 패턴
  • Original 객체를 새로운 객체에 복사하여 필요에 따라 수정하는 메커니즘 제공
  • Java의 경우 clone()을 사용하여 객체를 복사

객체를 복사할 때의 문제

  • 객체 복사본 생성
    1. 같은 클래스의 객체 생성
    2. 원본 객체의 필드를 모두 탐색하여 복사
  • 문제점
    • 객체의 필드가 일부 비공개일 수 있음
    • 객체의 복사본을 생성하려면 해당 객체의 클래스를 알아야 하므로 해당 클래스에 의존하게 됨
    • 인터페이스를 사용할 때 구현 클래스는 알 수 없음

프로토타입 패턴을 통한 해결

  • 복제되는 객체들에 복제 프로세스를 위임
  • 복제를 지원하는 모든 객체에 대한 공통 인터페이스 선언
  • clone 메서드를 통해 현재 클래스의 객체를 만든 후 이전 객체의 모든 필드 값을 새 객체로 전달

프로토타입 패턴 구조

  1. 프로토타입(prototype)
    • 인터페이스로 복제 메서드인 clone()을 선언한다.
  2. 구상 프로토타입(ConcretePrototype)
    • 복제 메서드를 구현하는데 원본 객체를 복사하는 것 이외에 복제 프로세스와 관련된 예외처리도 가능
  3. 클라이언트
    • 프로토타입 인터페이스를 따르는 모든 객체의 복사본을 생성

장점

  • 구상 클래스에 의존하지 않고 복제할 수 있음
  • 반복되는 초기화 코드 없이 프로토타입을 복제하여 객체를 생성할 수 있음
  • 복잡한 객체들을 쉽게 생성할 수 있음

단점

  • 순환 참조가 있는 복잡한 객체들을 복제할 때 까다로움

프로토타입 패턴 구현

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