디자인패턴

프로토타입(Prototype) 패턴

JUNGKEUNG 2022. 7. 8. 23:49
반응형

프로토타입 패턴 이란?

인스턴스를 사용해 새롭게 생성할 객체의 종류를 명시하여 새로운 객체가 생성될 시점에 인스턴스의 타입이 결정되도록 하는 패턴이다.

인프런 디자인 패턴(백기선) - 프로토타입

 

 

적용 가능한 경우

1. 코드가 복사해야 하는 구현 클래스에 의존하지 않아야 하는 경우 프로토타입 패턴을 사용할 수 있다.

  • 이 경우는 코드가 인터페이스를 통해 써드파티 코드와 함꼐 작동할 경우 많이 발생한다.

2. 객체를 초기화 하는 방식만 다를뿐 서브클래스의 수를 줄이려는 경우 프로토타입 패턴을 사용할 수 있다.

 

 

 

장단점

장점

  • 복한 객체를 만드는 과정을 숨길 수 있다
  • 기존 객체를 복제하는 과정이 새 인스턴스를 만드는 것보다 비용(시간 또는 메모리)적인 면에서 효율적일 수도 있다
  • 추상적인 타입을 리턴할 수 있다

 

단점

  • 복제한 객체를 만드는 과정 자체가 복잡할 수 있다.

 

 

 

예시

public class App {
    public static void main(String[] args) {
        GithubRepository repository = new GithubRepository();
        repository.setUser("whiteship");
        repository.setName("live-study");
        
        //기존 인스턴스
        GithubIssue githubIssue = new GithubIssue(repository);
        githubIssue.setId(1);
        githubIssue.setTitle("1주차 과제: JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가.");
        String url = githubIssue.getUrl();
        System.out.println(url);
        
        //새로운 인스턴스 생성 X
        GithubIssue githubIssue2 = new GithubIssue(repository);
        githubIssue2.setId(2);
        githubIssue2.setTitle("1주차 과제: JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가.");

        GithubIssue clone = githubIssue.clone();
    }
}

 위에 예시 처럼 새로운 인스턴스를 생성하지 말고 Java에 Object에서 제공해주는 Clone 사용해보자

@Override
protected Object clone() throws CloneNotSupportedException {
    return super.clone ();
}

오버 라이딩 해줘야한다.

 @Override
    protected Object clone() throws CloneNotSupportedException {
        GithubRepository repository = new GithubRepository();
        repository.setUser(this.repository.getUser());
        repository.setName(this.repository.getName());

        GithubIssue githubIssue = new GithubIssue(repository);
        githubIssue.setId(this.id);
        githubIssue.setTitle(this.title);

        return githubIssue;
    }
public class App {

    public static void main(String[] args) throws CloneNotSupportedException {
        GithubRepository repository = new GithubRepository();
        repository.setUser("whiteship");
        repository.setName("live-study");

        GithubIssue githubIssue = new GithubIssue(repository);
        githubIssue.setId(1);
        githubIssue.setTitle("1주차 과제: JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가.");

        String url = githubIssue.getUrl();
        System.out.println(url);

        GithubIssue clone = (GithubIssue) githubIssue.clone();
        System.out.println(clone.getUrl());

        repository.setUser("Keesun");

        System.out.println(clone != githubIssue);
        System.out.println(clone.equals(githubIssue));
        System.out.println(clone.getClass() == githubIssue.getClass());
        System.out.println(clone.getRepository() == githubIssue.getRepository());

        System.out.println(clone.getUrl());
    }

}

---------------------------------------------------------------------
결과 값
https://github.com/whiteship/live-study/issues/1
https://github.com/whiteship/live-study/issues/1
true
true
true
true
https://github.com/whiteship/live-study/issues/1

 

 

Script

  • 기존에 있는 인스턴스를 프로토타입을 사용해서 새로운 인스턴스를 생성하는 것이다.
  • clone 인터페이스를 만들어 구현을 생헝해야되지만 자바를 사용하고 있다면 ObjectClass가 제공하는 clone을 사용하면 된다. 그대신 interface Cloneable 만들어 줘야한다.
  • 프로토타입 패턴은 db에서 빈번하게 데이터를 가져올때, 그 데이터가 항상 똑같은 값을 반환하는 경우 유용하게 사용할 수 있다. db에서 그때마다 가죠오는 것이 좋은것 처럼 보일수 있지만. db에 접근하는데 사용하는 자원, 비용이 객체를 복사하는 비용보다 훨씬 크다는것을 염두해 두는것이 좋다

 

 

 

참고


https://keencho.github.io/posts/prototype-pattern/

https://www.inflearn.com/course/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4/dashboard

 

코딩으로 학습하는 GoF의 디자인 패턴 - 인프런 | 강의

디자인 패턴을 알고 있다면 스프링 뿐 아니라 여러 다양한 기술 및 프로그래밍 언어도 보다 쉽게 학습할 수 있습니다. 또한, 보다 유연하고 재사용성이 뛰어난 객체 지향 소프트웨어를 개발할

www.inflearn.com