java
Design Patterns - Prototype
쭈꾸마뇽
2021. 11. 22. 22:13
기존 인스턴스를 복제하여 새로운 인스턴스를 만드는 방법
복제 기능을 갖추고 있는 기존 인스턴스를 프로토타입으로 사용해 새 인스턴스를 만들 수 있다.
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);
}
}
프로토타입 패턴을 사용하기 위해선 Cloneable을 상속해야 하며 clone() 메서드를 오버라이딩 해야한다. 인텔리제이가 생성하는 clone() 메서드는 Object의 clone을 그대로 호출한다.
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
이 경우 객체는 얕은 복사가 되며 clone으로 만들어진 객체는 결국 원본 객체와 같은 객체로 볼 수 있다. 그렇기에 깊은 복사를 해야하는데 위처럼 직접 객체를 생성해주고 초기화하는 방법으로 구현할 수 있다.
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;
}
}
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());
}
}
- 장점
- 복잡한 객체를 만드는 과정을 숨길 수 있다
- 기존 객체를 복제하는 과정이 새 인스턴스를 만드는 것보다 비용(시간 또는 메모리)적인 면에서 효율적일 수도 있다
- 추상적인 타입을 리턴할 수 있다
- 단점
- 복제한 객체를 만드는 과정 자체가 복잡할 수 있다(특히, 순환 참조가 있는 경우)
코딩으로 학습하는 GoF의 디자인 패턴 - 인프런 | 강의
디자인 패턴을 알고 있다면 스프링 뿐 아니라 여러 다양한 기술 및 프로그래밍 언어도 보다 쉽게 학습할 수 있습니다. 또한, 보다 유연하고 재사용성이 뛰어난 객체 지향 소프트웨어를 개발할
www.inflearn.com