생성 패턴 - Prototype

이유석·2022년 6월 8일
0

Design Pattern

목록 보기
5/10
post-thumbnail
post-custom-banner

Prototype Pattern

정의

  • Original 객체를 새로운 객체에 복사하여 필요에 따라 수정하는 메커니즘을 제공합니다.

사용되는 경우

  • 객체를 생성하는데 비용(시간과 자원)이 많이 들고, 비슷한 객체가 이미 있는 경우에 사용됩니다.

구현 방법

  • Java 의 Cloneable을 구현하여, clone() 메소드를 정의 후 사용합니다.

예제 코드

  • DB로부터 데이터를 가져오는 객체가 존재한다고 가정해보겠습니다.
  • 만약 DB로부터 가져온 데이터를 프로그램에서 수차례 수정을 해야하는 요구사항이 있는 경우, 매번 new 라는 키워드를 통해 객체를 생성하여 DB로부터 항상 모든 데이터를 가져오는 것은 좋은 아이디어가 아닙니다.
    왜냐하면 DB로 접근하여 데이터를 가져오는 행위는 비용이 크기 때문입니다.
  • 따라서 한 번 DB에 접근하여 데이터를 가져온 객체를 필요에 따라 새로운 객체에 복사하여 데이터 수정 작업을 하는 것이 더 좋은 방법입니다.
  • 이때 객체의 복사를 얕은 복사(shallow copy)로 할 지, 깊은 복사(deep copy)로 할 지에 대해서는 선택적으로 하시면 됩니다.

실제 DB와 연동되는 예제 코드를 작성하는 것은 복잡할 수 있으므로, 직원의 명단을 갖고있는 Employees 클래스를 통해 살펴보겠습니다.

public class Employees implements Cloneable {
	
    private List<String> empList;
    
    public Employees() {
    	empList = new ArrayList<String>();
    }
    
    public void loadData() {
    	// 실제 DB와 연동되는 코드는 복잡하니 list에 직접 데이터를 넣어주겠습니다.
        empList.add("Pankaj");
        empList.add("Raj");
        empList.add("David");
        empList.add("Lisa");
    }
    
    public List<String> getEmpList() {
    	return empList;
    }
    
    // clone() 메소드를 정의하여 해당 객체를 복사하여 반환해줍니다.
    @Override
    public Object clone() throws CloneNotSupportedException {
    	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(); // 최초에는 DB에 연결하여 데이터를 불러옵니다.
        
        // 이후에는 clone() 메소드를 사용하여 최초에 불러온 객체를 복사하여 필요에 맞게사용합니다.
		Employees empsNew = (Employees) emps.clone();
        
        Employees empsNew1 = (Employees) emps.clone();
        List<String> list = empsNew.getEmpList();
        list.add("John");
        
        List<String> list1 = empsNew1.getEmpList();
        list1.remove("Pankaj");
		
        System.out.println("emps List: "+emps.getEmpList());
        System.out.println("empsNew List: "+list);
        System.out.println("empsNew1 List: "+list1);        
        
    }
}
emps List: [Pankaj, Raj, David, Lisa]
empsNew List: [Pankaj, Raj, David, Lisa, John]
empsNew1 List: [Raj, David, Lisa]

만약 Employees 클래스에서 clone()을 제공하지 않았다면, DB로부터 매번 employee 리스트를 직접 가져와야 했을 것이고, 그로 인해 상당히 큰 비용이 발생했을 것입니다.

하지만 프로토타입을 사용한다면 1회의 DB 접근을 통해 가져온 데이터를 복사하여 사용한다면 이를 해결할 수 있습니다. (객체를 복사하는 것이 네트워크 접근이나 DB 접근보다 훨씬 비용이 적습니다.)

profile
소통을 중요하게 여기며, 정보의 공유를 통해 완전한 학습을 이루어 냅니다.
post-custom-banner

0개의 댓글