본문 바로가기

강의/Design pattern

프로토타입 (Prototype) 패턴

SMALL

https://velog.io/@sillutt/%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85-Prototype-%ED%8C%A8%ED%84%B4

 

프로토타입 (Prototype) 패턴

프로토타입 패턴

velog.io

프로토타입 패턴

기존 인스턴스를 복제하여 새로운 인스턴스를 만드는 방법
복제 기능을 가진 기존 인스턴스를 프로토타입으로 사용하여 새 인스턴스를 만들어 일부를 변경하여 사용한다.
기존의 인스턴스 생성에 시간이 오래 걸리는 경우 (DB를 읽어 생성, 네트워크의 API요청 데이터 기반 등)

public class App {
	public static void main(String[] args) {
    	GithubRepository repository = new GithubRepository();
        repository.setUser("user");
        repository.setName("name");
        
        GithubIssue githubIssue = new GithubIssue(repository);
        githubIssue.setId(1);
        githubIssue.setTitle("title");
        
        String url = gethubIssue.getUrl();
        
        GithubIssue clone = githubIssue.clone();
        
        //TODO clone != githubIssue (객체의 레퍼런스가 다름)
        //TODO clone.equals(githubIssue) => true (내부 데이터가 같은지 체크)

사용방법

clone()은 자바가 제공하는 기능을 그대로 사용할 수 있다.
clone()은 Object내에 들어있다. clone()은 protected이기 때문에 명시적으로 사용할 수 있도록 만들어야 한다.

  • interface에 Clonable 구현하기
  • clone() override하기
@Override
protected Object clone() throws CloneNotSupportedException {
	return super.clone();
}

Deep copy

자바는 기본적으로 얕은 복사를 제공한다. clone()을 하면 기존의 객체와 같은 값을 참조하고 있다. 따라서 기존의 객체 내부 값이 변경되면 복사된 객체 내부의 값도 변경된다. 대신 Deep copy를 사용하면 기존 객체와 다른 새로운 객체를 복사할 수 있다.

Code

@Override
protected Object clone() throws CloneNotSupportedException {
	// 추가
    GithubRepository repository = new GithubRepository();
    repository.setUser(this.repository.getUser());
    respository.setName(this.repository.getName());
     
    // ...githubIssue create
    
	return githubIssue;
}

장단점

장점

  • 복잡한 객체를 만드는 과정을 clone() 내부에 숨길 수 있다.
  • 기존 객체를 복제하는 과정의 비용이 크다면 절약할 수 있다.
  • 추상적인 타입을 return할 수 있다. (해당 클래스와 반드시 동일할 필요가 없어 유연함)

단점

  • 순환 참조가 있는 경우 객체를 만드는 과정이 복잡해질 수 있다.

사용 예

List, ArrayList

List의 경우 clone을 제공하지 않기 때문에 clonable을 상속받는 ArrayList의 생성자를 사용한다.

엄밀히 따지면 프로토타입은 아니지만 실무에서는 낮은 복사로 사용하는 방법이다. clone()보다 자주 사용하는 방법이다.
List<Student> clone = new ArrayList(students);

ModelMapper

model mapper page
reflection 개념을 활용한 방법이다.

ModelMapper modelMapper = new ModelMapper();
// datasource와 data class를 넘겨준다.
GithubIssueData githubIssueData = modelMapper.map(githubIssue, githubIssueData.class);
SMALL

'강의 > Design pattern' 카테고리의 다른 글

브릿지 (Bridge) 패턴  (0) 2022.08.16
어댑터 (Adapter) 패턴  (0) 2022.08.16
빌더 (Builder) 패턴  (0) 2022.08.16
추상 팩토리 (Abstract factory) 패턴  (0) 2022.08.16
팩토리 메소드 (Factory method) 패턴  (0) 2022.08.16