728x90
반응형
애플리케이션을 개발하다 보면 객체를 생성하는 데 비용이 너무 많이 들거나, 기존 객체와 아주 유사한 객체를 여러 개 만들어야 하는 상황이 발생합니다. 이때 new 키워드로 매번 새로 생성하는 대신, 기존 객체를 복제하여 사용하는 프로토타입 패턴(Prototype Pattern)이 해결책이 될 수 있습니다.

1. 프로토타입 패턴이란?
프로토타입 패턴은 인스턴스를 새로 만드는 대신 기존에 있는 인스턴스를 복사(Clone)하여 새로운 객체를 생성하는 패턴입니다.
왜 사용하는가?
- 객체 생성 비용 절감: DB 조회 결과나 외부 API 연동을 통해 만들어진 복잡한 객체를 반복해서 만들 때 성능을 획기적으로 개선합니다.
- 초기화 과정 생략: 복잡한 초기 설정 과정을 거친 객체의 현재 상태를 그대로 복제하고 싶을 때 유용합니다.
- 클래스 의존성 제거: 구체적인 클래스 타입을 몰라도 인터페이스만 있다면 객체를 복제할 수 있습니다.
2. 핵심 이슈: 얕은 복사 vs 깊은 복사
프로토타입 패턴 구현 시 가장 주의해야 할 점은 복사의 깊이입니다.
| 구분 | 얕은 복사 (Shallow Copy) | 깊은 복사 (Deep Copy) |
| 특징 | 필드 값만 복사 (참조 변수는 주소만 복사) | 참조하는 객체까지 새로 생성하여 복사 |
| 결과 | 원본과 복제본이 내부 객체를 공유 | 원본과 복제본이 완전히 독립적 |
| 위험성 | 복제본 수정 시 원본 데이터가 변할 수 있음 | 메모리 사용량이 상대적으로 많음 |
3. Java 구현 예제: 깊은 복사 적용
자바에서 제공하는 Cloneable 인터페이스를 활용하여, 내부 객체까지 안전하게 복제하는 예제를 살펴보겠습니다.
Step 1. 모델 클래스 정의
Java
// 내부 참조 객체
class Author {
private String name;
public Author(String name) { this.name = name; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}
// Prototype 구현 클래스
class Book implements Cloneable {
private String title;
private Author author;
public Book(String title, String authorName) {
this.title = title;
this.author = new Author(authorName);
}
@Override
public Book clone() {
try {
// 1. 기본 얕은 복사 수행
Book cloned = (Book) super.clone();
// 2. 깊은 복사 수행: 내부 객체도 새로 복제하여 연결
cloned.author = new Author(this.author.getName());
return cloned;
} catch (CloneNotSupportedException e) {
throw new AssertionError(); // 일어날 수 없는 상황
}
}
public void showInfo() {
System.out.println("도서명: " + title + " | 저자: " + author.getName());
}
// Getter, Setter 생략
}
Step 2. 클라이언트 코드 실행
Java
public class Main {
public static void main(String[] args) {
Book original = new Book("디자인 패턴", "GoF");
// 객체 복제
Book copy = original.clone();
copy.setAuthorName("John Doe"); // 복제본의 저자 변경
System.out.println("--- 원본 데이터 ---");
original.showInfo(); // 여전히 GoF 유지 (깊은 복사 덕분)
System.out.println("--- 복제 데이터 ---");
copy.showInfo(); // John Doe로 변경됨
}
}
4. 프로토타입 패턴의 장단점
👍 장점
- 성능 최적화: 복잡한 객체 생성 과정을 건너뛰어 실행 속도를 높입니다.
- 런타임 유연성: 프로그램 실행 중에 객체의 복사본을 동적으로 생성할 수 있습니다.
👎 단점
- 깊은 복사의 복잡성: 참조 관계가 복잡한 객체일수록 모든 경로를 수동으로 복제해줘야 하므로 구현이 까다롭습니다.
- Cloneable의 한계: 자바의 clone() 메서드는 생성자를 호출하지 않아 객체 생성 방식이 다소 기형적이라는 비판이 있습니다.
5. 결론: 언제 사용해야 할까?
프로토타입 패턴은 "객체의 생성 과정이 런타임에 결정되거나, 생성 비용이 비쌀 때" 빛을 발합니다. 만약 자바의 clone() 방식이 복잡하게 느껴진다면, 최근 실무에서 더 권장되는 복사 생성자(Copy Constructor) 방식을 대안으로 고려해 보시기 바랍니다.
글이 도움이 되셨다면 공감과 구독 부탁드립니다!
반응형
'Mobile & App Stack > Java Software Architecture & Patterns' 카테고리의 다른 글
| 데코레이터 패턴 완벽 정리: 상속 없이 객체 기능 확장하기 (0) | 2024.12.25 |
|---|---|
| 어댑터 패턴(Adapter Pattern) 완벽 정리: 레거시 코드 통합의 열쇠 (0) | 2024.12.24 |
| 빌더 패턴(Builder Pattern) 완벽 정리: 생성자 대신 사용하는 이유와 구현법 (0) | 2024.12.22 |
| 추상 팩토리 패턴(Abstract Factory) 핵심 정리: 팩토리 메서드와 차이점은? (0) | 2024.12.21 |
| 팩토리 메서드 패턴(Factory Method Pattern) 완벽 정리: 왜 사용할까? (Java 예제) (0) | 2024.12.20 |