[패캠강의] 프로토 타입 패턴
2022. 1. 12. 20:59ㆍ디자인 패턴
728x90
[패캠강의] 프로토 타입 패턴
복잡한 클래스의 인스턴스를 생성할 때 하나의 견본(prototype)을 만들어 초기화해두고 이를 복제해서 객체를 사용하는 방법입니다. (Java clone() 메서드라고 생각하시면 됩니다.)
예제코드를 보면 바로 이해할 수 있을 겁니다.
주의할 점은 Mark interface(override해야할 메서드가 없이 특성만 알려주는 인터페이스) Cloneable
과 깊은 복사
입니다. 참고로 Arrays.copyOf() 메서드도 깊은 복사를 채택합니다.
//Arrays.copyOf() 메서드 docs, 새로운 배열을 만들어서 System.arraycopy 해줍니다.
public static int[] copyOf(int[] original, int newLength) {
int[] copy = new int[newLength];
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
package com.baekho.design.pattern.prototype;
import java.util.ArrayList;
import java.util.List;
class Book {
private String author;
private String title;
public Book(String author, String title) {
this.author = author;
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String toString() {
return "(" + author + ", " + title + ")";
}
}
class BookShelf implements Cloneable { //함부로 외부에서 변경해선 안되는 객체, mark 인터페이스 Cloneable를 사용해줍니다.
private List<Book> shelf;
public BookShelf() {
shelf = new ArrayList<>();
}
public void add(Book book) {
if (book == null) {
throw new NullPointerException("Book is null!");
}
shelf.add(book);
}
public List<Book> getShelf() {
return shelf;
}
public void setShelf(List<Book> shelf) {
this.shelf = shelf;
}
@Override
protected Object clone() throws CloneNotSupportedException {
//얕은 복사
// return super.clone();
//깊은 복사
BookShelf another = new BookShelf();
this.getShelf().forEach(b -> another.add(new Book(b.getAuthor(), b.getTitle())));
return another;
}
public String toString() {
return shelf.toString();
}
}
public class PrototypeTest {
public static void main(String[] args) throws CloneNotSupportedException {
BookShelf bookShelf = new BookShelf();
bookShelf.add(new Book("김승호","돈의속성"));
bookShelf.add(new Book("무라카미 하루키","해변의 카프카"));
bookShelf.add(new Book("장 폴 사르트르","존재와 무1"));
System.out.println(bookShelf);
BookShelf anotherBookShelf = (BookShelf) bookShelf.clone();
System.out.println("anotherBookShelf:: " + anotherBookShelf);
bookShelf.getShelf().get(0).setAuthor("한강");
bookShelf.getShelf().get(0).setTitle("채식주의자");
//주소를 복제해주는 얕은복사였기 때문에 같은 주소를 가리키고 있습니다.
System.out.println(bookShelf);
System.out.println("anotherBookShelf:: " + anotherBookShelf);
}
}
/* 출력:
[(김승호, 돈의속성), (무라카미 하루키, 해변의 카프카), (장 폴 사르트르, 존재와 무1)]
anotherBookShelf:: [(김승호, 돈의속성), (무라카미 하루키, 해변의 카프카), (장 폴 사르트르, 존재와 무1)]
[(한강, 채식주의자), (무라카미 하루키, 해변의 카프카), (장 폴 사르트르, 존재와 무1)]
anotherBookShelf:: [(김승호, 돈의속성), (무라카미 하루키, 해변의 카프카), (장 폴 사르트르, 존재와 무1)]
*/
참고자료
'디자인 패턴' 카테고리의 다른 글
[SOLID] 리스코프 치환 원칙(Liskov substitution principle) (0) | 2022.05.25 |
---|---|
[SOLID] 개방 폐쇄 원칙(Open-closed principle) (0) | 2022.05.25 |
[패캠강의] 빌더패턴 (0) | 2022.01.15 |
[패캠강의] 팩토리 메서드 패턴 (0) | 2022.01.01 |
[패캠강의] 1장_객체지향의 설계 (0) | 2021.12.31 |