(인프런) 코딩으로 학습하는 GoF의 디자인 패턴 - 백기선, 강의를 보고 정리한 글입니다.
코드는 GitHub 에 있습니다
#1. 객체 생성 관련 패턴 |
#2. 구조 관련 패턴 |
#3. 행동 관련 패턴 |
||
✔️ 프로토타입 패턴
- 기존 인스턴스를 복제하여 새로운 인스턴스를 만드는 방법
- 기존의 객체를 응용해서 새로운 객체를 만들 때 유용한 패턴입니다.
- 📌 기존의 객체를 생성할 때 시간이 오래걸릴 때 유용합니다.
- ex) DB 데이터 조회 및 네트워크 요청 후 HTTP 통신을 거친 데이터를 이용해 객체를 생성해야할 때 큰 리소스를 사용하기 때문
→ prototype 인터페이스가 가지는 clone() 메소드를 이용해 객체를 복제해서 사용한다는 개념입니다.
(Java 같은경우 Object.class 에 clone( ) 메소드가 구현되어있습니다.)
✔️ 프로토타입 패턴 특징
프로토타입의 매커니즘은 매우 단순합니다. 객체를 새롭게 생성하는데 큰 리소스가 드는 객체의 값을 모두 복제해 새로운 인스턴스를 만든는 것이 프로토타입 패턴입니다.
값을 복제하기 때문에 2가지 특징을 만족해야 합니다.
- clone != gitHubIssue → 다른 인스턴스가 새로 만들어지기 때문에 clone 한 객체는 기존 객체와 다른 객체여야 합니다.
- clone.equals(githubIssie) = true → 값을 모두 동일하게 복제하기 때문에 equals() 는 true 여야 합니다.
public class App {
public static void main(String[] args) {
GithubIssue githubIssue = new GithubIssue();
githubIssue.setId(1);
githubIssue.setTitle("title");
//clone
GithubIssue clone = githubIssue.clone();
//todo 1. clone != gitHubIssue (다른 인스턴스가 새로 만들어짐)
//todo 2. clone.equals(githubIssie) = true (값은 같아야함)
}
}
✔️ 프로토타입 패턴 구현하기
프로토타입 패턴은, 기존의 다른 패턴과 다르게 새롭게 구현하지 않고 Java 에서 제공해주는 clone( ) 기능을 그대로 사용해준다고 합니다.
Objects.class clone( )
- 기본적으로 자바가 제공하는 clone() 메소드를 이용해서 프로토타입 패턴을 구현할 수 있습니다.
- Object.class에서 제공하는 clone() protected 접근제어자로 정의가 되어있기 때문에 clone( ) 을 사용하고자하는 객체에서 재정의해서 사용하여야 합니다.
📌 프로토타입 패턴을 적용할 객체
- 먼저 clone() 을 사용할 객체에 Cloneable 인터페이스를 상속받아 clone 메소드를 구현하여야 합니다.
- clone() 은 Object class 의 주석에도 나와있다 싶이 CloneNotSuppretedException 을 체크해주어야만 합니다.
@Setter
@Getter
@EqualsAndHashCode //값비교를 위해 사용
public class GithubIssue implements Cloneable {
private int id;
private String title;
//공변 → Object.class 는 명시적으로 상속받고 있지않아도 객체 생성시 상속을 받음
@Override
public GithubIssue clone() {
try {
GithubIssue clone = (GithubIssue) super.clone();
// TODO: copy mutable state here, so the clone can't change the internals of the original
return clone;
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
}
👏🏻 Object.class를 반환해야할 clone() 메소드가 하위 클래스를 반환하는 공변 상태 입니다.
- → 모든 객체는 Object.class 는 명시적으로 상속받고 있지않아도, 상속을 받음
👏🏻 참고
- Object.class 의 clone() 은 얕은 복사(shallow copy) 를 제공합니다.
- 깊은 복사(deep copy)를 하고 싶다면, 자바에서 제공하는 clone( ) 메소드를 그대로 사용하지않고 새로 정의해야 합니다.
✔️ 프로토타입 패턴 장점 및 단점
장점
- 복잡한 객체를 만드는 과정을 숨길 수 있다.
- 기존 객체를 복제하는 과정이 새 인스턴스를 만드는 것보다 비용(시간 또는 메모리)적인 면에서 효율적일 수도 있다.
- 추상적인 타입을 리턴할 수 있다. (clone() 메소드를 커스텀하게 정의할 수 있으므로)
단점
- 복제한 객체를 만드는 과정 자체가(클론의 과정 자체가) 복잡할 수 있다. (특히, 순환 참조가 있는 경우)
✔️ 프로토타입 (Prototype) 패턴 실무에서 어떻게 쓰이나?
1. 자바 Object 클래스의 clone 메소드와 Cloneable 인터페이스
- 단순하게 ArrayList 만 보아도 Cloneable을 상속받고 있습니다.
- 그러나, clone() 메소드는 얕은복사를 제공하고, 보통의 경우 아래와 같이 인터페이스를 반환하기 때문에 생성자를 이용해서 객체를 복사하는 방법을 주로 사용합니다.
//clone 을 사용할 수 있지만 인터페이스를 반환하기위해 생성자 사용
List<GithubIssue> originList = List.of(githubIssue, clone);
List<GithubIssue> cloneList = new ArrayList<>(originList);
2. shallow copy와 deep copy
3. ModelMapper 라이브러리
'Java > Design Pattern' 카테고리의 다른 글
[디자인 패턴] 구조 패턴 - 브릿지 패턴 (Bridge Patterns) (2) | 2023.02.24 |
---|---|
[디자인 패턴] 구조 패턴 - 어댑터 패턴 (Adapter Patterns) (0) | 2023.02.16 |
[디자인 패턴] 생성패턴 - 빌더 패턴 (Builder Patterns) (0) | 2023.02.10 |
[디자인 패턴] 생성패턴 - 추상 팩토리 패턴 (Abstract Factory patterns) (0) | 2023.02.09 |
[디자인 패턴] 생성패턴 - 팩토리 메소드 패턴이란 (Factory Method patterns) (1) | 2023.02.08 |