프로토타입

ynkim·2024년 11월 28일
0

프로토타입

코드를 클래스에 의존시키지 않고 기존 객체를 복사할 수 있도록 하는 생성 디자인 패턴

구조

  • 프로토타입 인터페이스: 복제 메서드들을 선언한다. 대부분 clone() 하나이다.
  • 구상 프로토타입: 복제 메서드를 구현한다. 원본 데이터를 복제본에 복사하는 것 외에도 연결된 객체를 복제하거나 재귀 종속성을 푸는 등 복제 프로세스와 관련된 다른 일들을 처리할 수도 있다.
  • 클라이언트: 프로토타입 인터페이스를 따르는 객체의 복사본을 생성한다.

예시 코드

abstract class Shape {
    int x;
    int y;
    String color;

    public Shape() {
    }

    // 프로토타입 생성자
    public Shape(Shape source) {
        if (source != null) {
            this.x = source.x;
            this.y = source.y;
            this.color = source.color;
        }
    }

    // 복제 메서드
    public abstract Shape clone();
}

class Rectangle extends Shape {
    int width;
    int height;

    public Rectangle() {
    }

    public Rectangle(Rectangle source) {
        super(source);
        if (source != null) {
            this.width = source.width;
            this.height = source.height;
        }
    }

    @Override
    public Shape clone() {
        return new Rectangle(this);
    }
}

class Circle extends Shape {
    int radius;

    public Circle() {
    }

    public Circle(Circle source) {
        super(source);
        if (source != null) {
            this.radius = source.radius;
        }
    }

    @Override
    public Shape clone() {
        return new Circle(this);
    }
}

class ShapeRegistry {
    private Map<String, Shape> shapes = new HashMap<>();

    public void addShape(String key, Shape shape) {
        shapes.put(key, shape);
    }

    public Shape getShape(String key) {
        Shape shape = shapes.get(key);
        if (shape != null) {
            return shape.clone();
        }
        throw new IllegalArgumentException("Shape not found: " + key);
    }
}

class Application {
    List<Shape> shapes = new ArrayList<>();
    ShapeRegistry registry;

    public Application() {
        registry = new ShapeRegistry();

        Circle defaultCircle = new Circle();
        defaultCircle.x = 10;
        defaultCircle.y = 10;
        defaultCircle.radius = 20;
        defaultCircle.color = "Red";
        registry.addShape("circle", defaultCircle);

        Rectangle defaultRectangle = new Rectangle();
        defaultRectangle.x = 15;
        defaultRectangle.y = 25;
        defaultRectangle.width = 10;
        defaultRectangle.height = 20;
        defaultRectangle.color = "Blue";
        registry.addShape("rectangle", defaultRectangle);

        shapes.add(registry.getShape("circle"));
        shapes.add(registry.getShape("rectangle"));
    }

    public void businessLogic() {
        List<Shape> shapesCopy = new ArrayList<>();
        for (Shape s : shapes) {
            shapesCopy.add(s.clone());
        }

        System.out.println("Original Shapes: " + shapes.size());
        System.out.println("Copied Shapes: " + shapesCopy.size());
    }

    public static void main(String[] args) {
        Application app = new Application();
        app.businessLogic();
    }
}
  • 프로토타입 레지스트리: 자주 사용하는 프로토타입들의 카탈로그를 저장하고 어떠한 검색 기준으로 프로토타입을 찾아 복사하는 용도로 사용

장단점

장점

  • 객체들을 구상 클래스에 결합하지 않고 복제할 수 있다.
  • 미리 만들어진 프로토타입을 복제하면서 반복 코드를 제거할 수 있다.
  • 복잡한 객체들을 더 쉽게 생성할 수 있다.
  • 복잡한 객체들에 대한 사전 설정들을 처리할 때 상속 대신 사용할 수 있다.

단점

  • 순환 참조가 있는 복잡한 객체는 복제하는 것이 까다로울 수 있다.

0개의 댓글