728x90
반응형
Prototype Pattern
기존 인스턴스를 복제하여 새로운 인스턴스를 만드는 방법
복제 기능을 갖추고 있는 기존 인스턴스를 프로토타입으로 사용해 새 인스턴스를 만들 수 있다.
기존 인스턴스를 복제하여 새로운 인스턴스를 만드는 방법
GithubIssue
- GithubIssue 객체에 .clone()메소드를 구현하여 현재의 객체를 복사하여 새로운 인스턴스를 만들 수 있다.
이때 .clone()은 Object 클래스에 기본으로 존재하는 메소드로, 이를 사용하기 위해서 Cloneable 인터페이스를 상속받는다.
- deep copy를 비교할 수 있는 equals 메소드를 직접 구현해주었다.
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 {
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;
}
@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);
}
@Override
public int hashCode() {
return Objects.hash(id, title, repository);
}
}
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;
}
}
App
- 위 예제의 clone 메소드 내부에서 GithubRepository를 새로 생성하여 주입하는 방식으로 복사를 해주었기 때문에 equals를 비교를 하면 false 가 나온다.
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());
}
}
[ 패턴 복습]
장점 | 단점 |
- 복잡한 객체를 만드는 과정을 숨길 수 있다. - 기존 객체를 복제하는 과정이 새 인스턴스를 만드는 것보다 비용(시간 또는 메모리)적인 면에서 효율적일 수도 있다. - 추상적인 타입을 리턴할 수 있다. (유연성) |
- 복제한 객체를 만드는 과정 자체가 복잡할 수 있다. (특히 순환 참조가 있는 경우) |
[실무에서 쓰이는 경우]
- 자바 Object 클래스의 clone 메소드와 Cloneable 인터페이스
- shallow copy와 deep copy
- ModelMapper
728x90
반응형
'Design Patterns > 생성(Creational)' 카테고리의 다른 글
[Builder]빌더패턴 (0) | 2022.05.26 |
---|---|
[Abstract factory]추상팩토리 (0) | 2022.05.25 |
[FactoryMethod]장점과 단점 (0) | 2022.05.20 |
[Singleton]4. 자바와 스프링에서 찾아보는 패턴 (0) | 2022.04.08 |
[Singleton]3. 안전하고 단순하게 구현하는 방법 (0) | 2022.04.07 |