프로토타입(prototype) 패턴
디자인 패턴 ·기존에 존재하는 객체를 복사해 생성하는 디자인 패턴이다
똑같은 상태를 가진 객체를 생성하는데 유리하다
![]()
예시
GithubRepository에 똑같은 이슈를 두개 생성하려고 한다.
프로토타입 패턴 구현 예제
Prototype에 Clonable을 구현하고, clone 함수를 오버라이드한다.
public class GithubIssue implements Cloneable {
private int id;
private String title;
private GithubRepository repository;
public GithubIssue(GithubRepository repository) {
this.repository = repository;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
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
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
GithubIssue that = (GithubIssue) o;
return id == that.id && Objects.equals(title, that.title) && Objects.equals(repository, that.repository);
}
}
Concreate Builder
public class DefaultTourPlanBuilder implements TourPlanBuilder {
private final List<DetailPlan> plans;
private String title;
private LocalDate startDate;
private int nights;
private int days;
private String whereToStay;
public DefaultTourPlanBuilder() {
this.plans = new ArrayList<>();
this.title = "";
this.startDate = LocalDate.now();
this.nights = 0;
this.days = 0;
whereToStay = "";
}
@Override
public TourPlanBuilder title(String title) {
this.title = title;
return this;
}
@Override
public TourPlanBuilder startDate(LocalDate startDate) {
this.startDate = startDate;
return this;
}
@Override
public TourPlan build() {
return new TourPlan(this.title, this.nights, this.days, this.startDate, this.whereToStay, this.plans);
}
@Override
public TourPlanBuilder nightsAndDays(int nights, int days) {
this.nights = nights;
this.days = days;
return this;
}
@Override
public TourPlanBuilder whereToStay(String whereToStay) {
this.whereToStay = whereToStay;
return this;
}
@Override
public TourPlanBuilder addPlan(int day, String plan) {
this.plans.add(new DetailPlan(day, plan));
return this;
}
}
GithubRepository
public class GithubRepository {
private String user;
private String name;
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Prototype 클라이언트 코드
class GithubIssueCloneTest {
@Test
public void clone_test() throws CloneNotSupportedException {
GithubRepository repository = new GithubRepository();
repository.setUser("kktrkkt");
repository.setName("live-study");
GithubIssue githubIssue = new GithubIssue(repository);
githubIssue.setId(1);
githubIssue.setTitle("1주차 과제: JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가.");
GithubIssue clone = (GithubIssue) githubIssue.clone();
assertTrue(clone != githubIssue);
assertEquals(githubIssue, clone);
assertEquals(githubIssue.getClass(), clone.getClass());
}
}
프로토타입 패턴은 객체 생성비용이 큰 경우 효율적이다
단, 복제하는 과정이 복잡하다면 오히려 비용이 증가될 수 있다.
예제는 이곳 에서 확인하실수 있습니다.