# 프로토타입 (Prototype) 패턴

# 프로토타입 패턴이란 무엇인가요?

생성할 객체들의 타입이 프로토타입인 인스턴스로부터 결정되도록 하는 것입니다. 쉽게 말해, 런타임에 Original 객체와 똑같은 속성을 가진 복사본을 만드는 것입니다. (복사본을 만들기 위해 clone 메소드를 사용합니다.)

# 예시 코드

  • 직원 명단을 가지고 있는 Employees 클래스 (프로토타입 패턴 사용)
public class Employees implements Cloneable{
    private List<String> empList;

    public Employees(){ //기본 생성자
        empList = new ArrayList<String>();
    }

    public Employees(List<String> list){    //전달 받은 list를 저장한 뒤 객체 생성
        this.empList = list;
    }

    public void loadData() {
        empList.add("백현");
        empList.add("김재욱");
        empList.add("이종석");
        empList.add("김우빈");
    }

    public List<String> getEmpList() {
        return empList;
    }

    @Override
    public Object clone() throws CloneNotSupportedException{    //clone메소드를 재정의해줌
        List<String> temp = new ArrayList<String>();
        for(String s : this.empList){
            temp.add(s);
        }
        return new Employees(temp); //생성자를 호출하여 새로운 객체를 생성해 준 뒤 반환
    }
}
  • 프로토타입 패턴 테스트
public class PrototypePatternTest {

    public static void main(String[] args) throws CloneNotSupportedException {
        Employees emps = new Employees();
        emps.loadData();
        
        Employees empsNew = (Employees) emps.clone();
        Employees empsNew1 = (Employees) emps.clone();
        List<String> list = empsNew.getEmpList();
        list.add("지창욱");
        List<String> list1 = empsNew1.getEmpList();
        list1.remove("김재욱");

        System.out.println("emps List: "+emps.getEmpList());
        System.out.println("empsNew List: "+list);
        System.out.println("empsNew1 List: "+list1);
    }
}
  • 테스트 결과
emps List: [백현, 김재욱, 이종석, 김우빈]
empsNew List: [백현, 김재욱, 이종석, 김우빈, 지창욱]
empsNew1 List: [백현, 이종석, 김우빈]

# 프로토타입 패턴은 언제 사용하나요?

프로토타입 패턴은 객체를 생성하는데 비용이 많이 들고, 비슷한 객체가 이미 있는 경우에 사용됩니다.
예를 들어, DB에서 가져온 데이터를 프로그램 상에서 수차례 수정을 해야 할때, 계속 DB에 접근해서 데이터를 가져오는 것은 비용이 많이 듭니다. 이때 한번 DB에 접근해서 가져온 객체를 필요에 따라 새로운 객체에 복사하여 사용하는 것이 프로토타입 패턴을 활용한 것입니다.

# 프로토타입 패턴의 장점은 무엇인가요?

  • 복잡한 객체를 만드는 과정을 clone안에 숨겨놓고 간단하게 사용이 가능합니다.
  • 구현 클래스에 직접 연결하지 않고 객체를 복사할 수 있습니다.

# 프로토타입 패턴의 단점은 무엇인가요?

  • 순환 참조가 있는 복잡한 객체를 복제하는 것이 까다롭습니다.

# 참고자료

출처: https://readystory.tistory.com/122 [준비된 개발자]
출처: https://keencho.github.io/posts/prototype-pattern/ [keencho's blog]