# 설명
객체를 만드는데 복잡하거나 여러자원이 소비되는 경우 프로토타입을 만들고, clone하여 사용하는 방식이다.
생성패턴중에 하나이다.
자바의 오브젝트 타입이 지원하는 clone()을 오버라이딩해서 사용한다. 단, super.clone()을 사용할 경우 인스턴스가 새로 생성되지만 얕은 복사가 된다. 그렇기 때문에 다른 곳에서 안에 객체를 수정할 경우 같이 수정 되기 때문에 깊은복사(deep-copy)를 할 수 있도록 재정의 해줘야 한다.
# 코드
// Book.java
package prototype;
public class Book {
private String title;
private String author;
public Book(String t, String a) {
title = t;
author = a;
}
public String getTitle() {
return title;
}
public String getAuthor() {
return author;
}
public void setTitle(String title) {
this.title = title;
}
public void setAuthor(String author) {
this.author = author;
}
@Override
public String toString() {
return "(" + title + "," + author +")";
}
}
// BookShelf.java
package prototype;
import java.util.ArrayList;
/*
깊은 복사를 위해 clone에서 super.clone() 을 호출하지 않고, 새롭게 만들어줌.
다형성을 이용했기 때문에 반환형이 Object타입이어도 BookShlef를 반환 가능함.
*/
// Cloneable을 상속 받아도 따로 정의할 건 없음, 명시해주는 인터페이스 이를 마크 인터페이스라고도함.
public class BookShelf implements Cloneable{
private ArrayList<Book> bookList;
public BookShelf() {
this.bookList = new ArrayList<Book>();
}
public ArrayList<Book> getBookList() {
return bookList;
}
public void addBook(Book book) {
bookList.add(book);
}
@Override
public String toString() {
return bookList.toString();
}
// 다형성을 이용했기 때문에 반환형이 Object타입이어도 BookShlef를 반환 가능
@Override
protected Object clone() throws CloneNotSupportedException {
BookShelf another = new BookShelf();
for ( Book book: bookList) {
another.addBook(new Book(book.getTitle(),book.getAuthor()));
}
return another;
}
}
# 테스트
// Test.java
package prototype;
/*
프로토타입 패턴.
생성 패턴 중에 하나이다.
DB로 부터 데이터를 가져와 수정 작업을 거칠때 매번 새로운 인스턴스를 호출하는 일은 자원 소모가 큰 일이기 때문에
프로토타입을 clone하는 방식을 사용함.
*/
public class Test {
public static void main(String[] args) throws CloneNotSupportedException{
BookShelf orginalShelf = new BookShelf();
orginalShelf.addBook(new Book("안드로이드 정복","김호준"));
orginalShelf.addBook(new Book("스프링 정복","이호준"));
orginalShelf.addBook(new Book("디자인 패턴 정복","박호준"));
System.out.println("orginalShelf : "+orginalShelf);
BookShelf copyShelf = (BookShelf)orginalShelf.clone(); // object로 반환하기 때문에 다운캐스팅을 해줘야함
System.out.println("copyShelf : "+copyShelf);
System.out.println("=========================");
// 깊은 복사가 이루어졌는지 확인
Book temp = copyShelf.getBookList().get(0);
temp.setAuthor("한강");
temp.setTitle("조정래");
System.out.println("orginalShelf : "+orginalShelf);
System.out.println("copyShelf : "+copyShelf);
}
}
- 복사본을 수정해도 프로토타입(원본)에는 영향을 끼치지 않는 것을 알 수 있다.
'• 독서 > Design Pattern' 카테고리의 다른 글
[디자인패턴-위임/팩토리패턴] 팩토리 메소드 패턴 (Factory-Method Pattern) (2) | 2022.09.20 |
---|---|
[디자인패턴-위임패턴] 템플릿 메서드 패턴(Template Method) (0) | 2022.09.18 |
[디자인패턴-생성패턴] 빌더 패턴(Builder Pattern) (2) | 2022.09.17 |
[디자인패턴-생성패턴] 추상팩토리 패턴(Abstract-Factory pattern) (0) | 2022.09.17 |
[디자인패턴-생성패턴] 싱글톤 패턴(Singleton Pattern) (0) | 2022.09.16 |