- 자바(JAVA) - 프로토타입(Frototype) 패턴
1. 의도
원형이 되는 인스턴스를 사용하여 생성할 객체의 종류를 명시하고, 이렇게 만든 견본을 복사해서 새로운 객체를 생성
즉, 기존 인스턴스를 복제하여 새로운 인스턴스를 만드는 것
2. 용도
객체를 생성하는데 비용이 많이 들고, 비슷한 객체가 이미 있는 경우에 사용
객체를 복사하여 필요에 따라 수정하는 메커니즘을 제공
3. UML
4. 구현
- 적용 전
public class Member {
private final String name;
private final String address;
private final BasicItem basicItem;
public Member(String name, String address, BasicItem basicItem) {
this.name = name;
this.address = address;
this.basicItem = basicItem;
}
public void desc() {
System.out.println("이름 : " + name);
System.out.println("주소 : " + address);
System.out.println("지원 아이템 : " + basicItem.getBag());
System.out.println("가방 이름 : " + basicItem.getBagInfo().getBagName());
}
}
=======================================================================
public class BagInfo {
private String bagName;
public String getBagName() {
return bagName;
}
public void setBagName(String bagName) {
this.bagName = bagName;
}
}
=======================================================================
public class BasicItem {
private final BagInfo bagInfo;
private final List<String> bag;
public BasicItem(BagInfo bagInfo) {
this.bagInfo = bagInfo;
this.bag = new ArrayList<>();
}
public BagInfo getBagInfo() {
return bagInfo;
}
public void add(String item) {
bag.add(item);
}
public void remove(String item) {
bag.remove(item);
}
public List<String> getBag() {
return bag;
}
}
=======================================================================
public class Client {
public static void main(String[] args) {
BagInfo bagInfo = new BagInfo();
bagInfo.setBagName("기본");
BasicItem basicItems = new BasicItem(bagInfo);
basicItems.add("책상");
basicItems.add("의자");
basicItems.add("컴퓨터");
basicItems.add("키보드");
basicItems.add("등등");
Member member = new Member("멤버1", "강남", basicItems);
member.desc();
System.out.println("===============================");
BagInfo bagInfo2 = new BagInfo();
bagInfo2.setBagName("기본");
BasicItem basicItems2 = new BasicItem(bagInfo2);
basicItems2.add("책상");
basicItems2.add("의자");
basicItems2.add("컴퓨터");
basicItems2.add("등등");
Member member2 = new Member("철수", "서울", basicItems2);
member2.desc();
}
}
/*
이름 : 멤버1
주소 : 강남
지원 아이템 : [책상, 의자, 컴퓨터, 키보드, 등등]
가방 이름 : 기본
===============================
이름 : 철수
주소 : 서울
지원 아이템 : [책상, 의자, 컴퓨터, 등등]
가방 이름 : 기본
*/
- 적용 후
public class BasicItem implements Cloneable{
private final BagInfo bagInfo;
private final List<String> bag;
public BasicItem(BagInfo bagInfo) {
this.bagInfo = bagInfo;
this.bag = new ArrayList<>();
}
public BagInfo getBagInfo() {
return bagInfo;
}
public void add(String item) {
bag.add(item);
}
public void remove(String item) {
bag.remove(item);
}
public List<String> getBag() {
return bag;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
===================================================================
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
BagInfo bagInfo = new BagInfo();
bagInfo.setBagName("기본");
BasicItem basicItems = new BasicItem(bagInfo);
basicItems.add("책상");
basicItems.add("의자");
basicItems.add("컴퓨터");
basicItems.add("키보드");
basicItems.add("등등");
Member member = new Member("멤버1", "강남", basicItems);
member.desc();
System.out.println("===============================");
BasicItem basicItems2 = (BasicItem) basicItems.clone();
System.out.println(basicItems != basicItems2);
System.out.println(basicItems.getClass() == basicItems2.getClass());
System.out.println(basicItems.getBagInfo() == basicItems2.getBagInfo());
basicItems2.remove("키보드");
bagInfo.setBagName("바뀜");
Member newMember = new Member("철수", "서울", basicItems2);
newMember.desc();
}
}
/*
이름 : 멤버1
주소 : 강남
지원 아이템 : [책상, 의자, 컴퓨터, 키보드, 등등]
가방 이름 : 기본
===============================
이름 : 철수
주소 : 서울
지원 아이템 : [책상, 의자, 컴퓨터, 등등]
가방 이름 : 바뀜
true
true
true
*/
문제점은 bagInfo.setBagName("바뀜"); 로 주입 받은 객체가 바뀐게 적용 됨. (얕은 복사)
@Override
protected Object clone() throws CloneNotSupportedException {
BagInfo bagInfo = new BagInfo();
bagInfo.setBagName(this.bagInfo.getBagName());
BasicItem basicItems = new BasicItem(bagInfo);
basicItems.add("책상");
basicItems.add("의자");
basicItems.add("컴퓨터");
basicItems.add("키보드");
basicItems.add("등등");
return basicItems;
}
/*
이름 : 멤버1
주소 : 강남
지원 아이템 : [책상, 의자, 컴퓨터, 키보드, 등등]
가방 이름 : 기본
===============================
이름 : 철수
주소 : 서울
지원 아이템 : [책상, 의자, 컴퓨터, 등등]
가방 이름 : 기본
true
true
false
*/
clone() 을 재 정의하여 깊은 복사로 바꾼다.
5. 패턴의 장단점
- 장점
- 복잡한 객체를 만드는 과정을 숨길 수 있다.
- 기존 객체를 복제하는 과정이 새 인스턴스를 만드는 것보다 비용(시간 or 메모리)적인 면에서 효율적일 수 있다.
- 추상적인 타입을 리턴할 수 있다.
- 단점
- 복제한 객체를 만드는 과정 자체가 복잡할 수 있다. (특히, 순환참조가 있는 경우)
출처 :
https://refactoring.guru/design-patterns/prototype
Prototype
/ Design Patterns / Creational Patterns Prototype Also known as: Clone Intent Prototype is a creational design pattern that lets you copy existing objects without making your code dependent on their classes. Problem Say you have an object, and you want to
refactoring.guru
'디자인 패턴' 카테고리의 다른 글
자바(JAVA) - 어댑터(Adapter) 패턴 (1) | 2023.11.21 |
---|---|
자바(JAVA) - 플라이 웨이트(Flyweight) 패턴 (0) | 2023.11.16 |
자바(JAVA) - 팩토리 메서드(Factory Method) 패턴 (0) | 2023.11.15 |
자바(JAVA) - 추상팩토리(Abstract Factory) 패턴 (2) | 2023.11.08 |
자바(JAVA) - 컴포지트(Composite) 패턴 (0) | 2023.11.02 |