프로토타입 패턴이란?

스크린샷 2023-09-29 오전 11.38.15.png

구현하기

자바 얕은 복사

public class GithubIssue implements **Cloneable** {

    private int id;

    private String title;

    private GithubRepository repository;

    public GithubIssue(GithubRepository repository) {
        this.repository = repository;
    }

    // getter, setter

    public String getUrl() {
        return String.format("<https://github.com/%s/%s/issues/%d>",
                repository.getUser(),
                repository.getName(),
                this.getId());
    }

    @Override
    public GithubIssue clone() {
        return (GithubIssue) super.clone(); // 얕은 복사(참조 복사)
    }
}

public class Client {
    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);

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

        // 참조 및 논리적 동일성 확인
        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());

        // Object.clone - 얕은 복사
        repository.setUser("Keesun"); // clone도 바뀜
        System.out.println(clone.getUrl()); // <https://github.com/Keesun/live-study/issues/1>

    }
}

깊은 복사

public class GithubIssue implements Cloneable {

    private int id;

    private String title;

    private GithubRepository repository;

    public GithubIssue(GithubRepository repository) {
        this.repository = repository;
    }

    public GithubRepository getRepository() {
        return repository;
    }

    public String getUrl() {
        return String.format("<https://github.com/%s/%s/issues/%d>",
                repository.getUser(),
                repository.getName(),
                this.getId());
    }

    @Override
    public GithubIssue clone() {

        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;

    }
}

장단점

장점