디자인 패턴
자바(JAVA) - 프로토타입(Prototype) 패턴
Hyeongjun_Ham
2023. 11. 20. 09:50
- 자바(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