Prototype Pattern

HeeSeong·2021년 9월 8일
0

Design Pattern

목록 보기
2/4
post-thumbnail

Prototype Pattern 이란?


생성할 객체들의 타입이 프로토타입인 인스턴스로부터 결정되도록 하며, 인스턴스는 새 객체를 만들기 위해 자신을 복제(clone)하게 된다.


1. 사용 의도 (Intent)


  • 클래스의 인스턴스가 생성과정이 복잡하거나 여러 조합에 의해 생성되어야하는 경우

2. 객체 협력 (collaborations)


  • 하나의 견본(prototype)을 만들어 초기화해두고 이를 복제해서 객체를 생성하는 방법

3. 결과 (consequence)


장점


예를 들어 DB로부터 데이터를 가져오는 객체가 존재한다고 가정한다. 만약 DB로부터 가져온 데이터를 우리의 프로그램에서 수차례 수정을 해야하는 요구사항이 있는 경우, 매번 DB로부터 항상 똑같은 데이터를 가져오는 것은 좋은 아이디어가 아니다. DB로 접근해서 데이터를 가져오는 행위는 비용이 크기 때문이다. 한 번 DB에 접근하여 데이터를 가져온 객체를 필요에 따라 새로운 객체에 복사하여 데이터 수정 작업을 하는 것이 더 좋은 방법이다. 객체의 복사를 얕은 복사(shallow copy)로 할 지, 깊은 복사(deep copy)로 할 지에 대해서는 필요에 따라 행한다.

  • 클래스로부터 인스턴스 생성이 어려운 경우 똑같은 인스턴스를 간단하게 생성할 수 있다

단점


  • 생성될 객체들의 자료형인 클래스들이 모두 clone() 함수를 구현해야 한다.

4. 예제 코드


  • Book
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 title + "," + author;
    }
}

  • BookShelf
import java.util.ArrayList;

class BookShelf implements Cloneable {

    private ArrayList<Book> shelf;

    public BookShelf() {
        shelf = new ArrayList<Book>();
    }

    public void addBook(Book book) {
        shelf.add(book);
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        BookShelf another = new BookShelf();
        // 깊은 복사 시행
        for (Book book : shelf) {
            another.addBook(new Book(book.getAuthor(), book.getTitle()));
        }
        return another;
    }

    public ArrayList<Book> getShelf() {
        return shelf;
    }

    public void setShelf(ArrayList<Book> shelf) {
        this.shelf = shelf;
    }

    public String toString() {
        return shelf.toString();
    }
}

  • Test
class Test {
    public static void main(String[] args) throws CloneNotSupportedException {

        BookShelf bookShelf = new BookShelf();
        bookShelf.addBook(new Book("orange", "Tomas"));
        bookShelf.addBook(new Book("apple", "James"));
        bookShelf.addBook(new Book("grape", "Edward"));

        BookShelf another = (BookShelf) bookShelf.clone();
        System.out.println("bookShelf = " + bookShelf);
        System.out.println("another = " + another);

        bookShelf.getShelf().get(0).setAuthor("Mango");
        bookShelf.getShelf().get(0).setTitle("Jane");
        System.out.println("bookShelf = " + bookShelf);
        System.out.println("another = " + another);
    }
}

결과


깊은 복사로 구현해서 clone()으로 복사했지만 주소값이 다른, 서로 다른 인스턴스이므로 첫 인스턴스의 값을 변경해주면, 다른 인스턴스의 값이 따라서 변하지 않는다.

bookShelf = [Tomas,orange, James,apple, Edward,grape]
another = [Tomas,orange, James,apple, Edward,grape]
bookShelf = [Jane,Mango, James,apple, Edward,grape]
another = [Tomas,orange, James,apple, Edward,grape]
profile
끊임없이 성장하고 싶은 개발자

0개의 댓글