프로토타입 패턴이란?
프로토타입은 보통 프로젝트에서 시제품, 시안 정도로 해석되는 공대에서 많이 쓰는 용어다. 프로그래밍에선 디테일한 의미가 조금 다르긴 하다만, 그 맥락과 뜻은 같이 하는 것 같다. 먼저, 공대에서 사용하는 프로토타입에 대해 간략하게 알아보자. (내가 이해한 부분임)
많은 전공 과목을 수강하며 프로토타입이란 단어를 한 학기도 들어보지 않았던 적이 없었다. 당시 이해했던 프로토타입은 제품의 기능을 빠르게 테스트하기 위해 만드는 시제품이라는 생각이었다. 그래서 구상하고자 하는 완성된 제품의 기능을 테스트 할 때 항상 프로토타입을 만들어서 테스트를 하곤 했다.
본격적인 프로그래밍, 디자인패턴에서의 프로토타입에 대해 살펴보자. 먼저, 가장 중요한 킹키백과의 내용은 다음과 같다.
프로토타입 패턴(prototype pattern)은 소프트웨어 디자인 패턴 용어로, 생성할 객체들의 타입이 프로토타입인 인스턴스로부터 결정되도록 하며, 인스턴스는 새 객체를 만들기 위해 자신을 복제(clone)하게 된다. - 위키 백과
말이 너무 어렵다. 조금 말을 풀어보고 이리저리 다듬어 보면 결국은 마지막 문장이 가장 중요하다. 인스턴스는 새 객체를 만들기 위해 자신을 복제하는 것. 결국 새 객체를 복사하여 인스턴스에 할당하게 하는 역할이라는 것이다. 결국 공대에서의 프로토타입도 완제품의 복제품이고 디자인패턴에서의 프로토타입 패턴도 복제품이라는 것을 알 수 있다. 다음으로 이 프로토타입이 왜 좋은지에 대해 알아보자.
왜 쓰냐?
만약에 하나의 객체를 생성하는데 큰 비용(시간, 자원)이 들었다고 해보자. (많은 과장을 보태어 한 객체 생성하는데 10분 이상 소요된다) 이 때, 이 객체를 또 다시 생성해야 한다면 10분이라는 시간 비용이 소모된다. 이건 분명한 낭비이자 문제이다. 이해를 돕기 위한 한 예를 더 들어보자, DB에서 데이터를 가져와서 생성하는 객체가 있는데 이 객체를 생성할 때마다 DB에 접근하는 것 또한 낭비다. 그래서 등장한 것이 프로토타입 패턴이다. 핵심은 이미 한 번 불러온거 그 거 그대로 복사해서 씁시다.
복사에도 종류가 있다.
프로토타입이 생성한 객체를 복사해서 새로운 객체에 할당하는 것이라는 뭔가 복사, 복제의 개념이라는 바이브가 느껴진다. 이런 복사, 복제에도 두 가지 종류가 있다. 얇은 복사와 깊은 복사이다. 간단하다.
위 그림에서도 알 수 있듯이, 얇은 복사는 서로 같은 객체를 참조하고 있기 때문에 원본과 복사본 둘 중에 어느 하나의 객체값이 변하면 둘 다 영향을 미친다. 즉, 서로 의존적이고 사람으로 따지면 영혼까지 복사한 셈이다.
다음으로 깊은 복사는 서로 다른 객체를 참조하고 있기 때문에 서로 값에 영향이 없다. 즉, 서로 독립이며 사람으로 따지면 외형은 똑같으나 각자 자아를 갖고 있는 셈이다.
프로토타입 패턴 코드 구현
상황 : 어떤 모양 ( Shape )을 그릴 수 있도록 하고, 복사-붙여넣기 기능 구현
추가 요구사항 : 복사될 때, 그림 안겹치게 해주세요.
* Triangle 클래스
package DesignPattern.Prototype;
public class Triangle extends Shape {
private int x, y, r;
public Triangle(int x, int y, int r) {
this.x = x;
this.y = y;
this.r = r;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public int getR() {
return r;
}
public void setR(int r) {
this.r = r;
}
public Triangle copy() throws CloneNotSupportedException {
Triangle triangle = (Triangle) clone();
// 복사-붙여넣기 할 때 완전히 겹치지 않게 하려고 위치값 조정해주는거
triangle.x = x + 1;
triangle.y = y + 1;
return triangle;
}
}
* Shape 클래스
package DesignPattern.Prototype;
// Cloneable은 정의되어 있는 인터페이스
public class Shape implements Cloneable {
// Shape은 구현체
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
* 테스트를 위한 코드
package DesignPattern.Prototype;
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
Triangle triangle1 = new Triangle(1, 1, 3);
Triangle triangle2 = triangle1.copy();
System.out.println (triangle1.getX()+ ", " + triangle1.getY() + ", " + triangle1.getR());
System.out.println (triangle2.getX()+ ", " + triangle2.getY() + ", " + triangle2.getR());
}
}
* 출력 결과
1, 1, 3
2, 2, 3
'Note' 카테고리의 다른 글
[Docker] 도커(Docker)란 무엇인가 (0) | 2022.02.08 |
---|---|
[디자인패턴] Singleton Pattern - 싱글톤 패턴 (0) | 2021.12.19 |
[디자인패턴] Decorator Pattern - 데코레이터 패턴 (0) | 2021.12.18 |
[디자인패턴] Composite Pattern - 복합체 패턴 (0) | 2021.12.17 |
[디자인패턴] Factory Pattern - 팩토리 패턴 (0) | 2021.12.16 |