04. [Design Pattern] 프로토타입(Prototype) 패턴

2023. 11. 7. 21:05· 프로그래밍 이론/디자인 패턴
목차
  1. 프로토타입 패턴
  2. 구조
  3. 기본 인터페이스
  4. 왜 사용해야 할까?
  5. 장점
  6. 단점
  7. 참고자료

프로토타입 패턴

원형이 되는 객체를 사용하여 생성할 객체의 종류를 명시하고, 이렇게 만든 견본을 복사해서 새로운 객체를 생성하는데 목적은 둔 패턴이다.


구조

  • Prototype : 자신을 복제하는 데 필요한 인터페이스를 정의한다.
  • ConcretePrototype - 자신을 복제하는 연산을 정의한다.
  • Client - 원형 객체에 자기 자신의 복제를 요청하여 새로운 객체를 생성한다.


기본 인터페이스

namespace Prototype;

//프로토타입 인터페이스
public interface Prototype
{
    public Prototype Clone();
}
//프로토타입 상속 클래스
public class ConcretePrototypeA : Prototype
{
    private int a;
    private int b;

    public ConcretePrototypeA(ConcretePrototypeA origin)
    {
        this.a = origin.a;
        this.b = origin.b;
    }
    public ConcretePrototypeA(int a, int b)
    {
        this.a = a;
        this.b = b;
    }

    public Prototype Clone()
    {
        ConcretePrototypeA clone = new ConcretePrototypeA(this);
        return clone;
    }

    public void Print()
    {
        Console.WriteLine($"a : {a}  b : {b}");
    }
}

public class MainTest
{
    public static int Main(string[] args)
    {
        //원본 생성
        ConcretePrototypeA origin = new ConcretePrototypeA(3, 5);
        origin.Print();
        //원본 복사
        ConcretePrototypeA clone = (ConcretePrototypeA)origin.Clone();
        clone.Print();
        
        return 0;
    }
}
a : 3 b : 5
a : 3 b : 5

 


왜 사용해야 할까?

단적으로 말하자면 객체를 복사하고 원본에서 독립시키기 위해 사용한다. 그림이나 사진을 복사할 때 복사본은 원본과 똑같은 값을 가지지만, 원본에서 독립하여 다른 형태로 변형하거나 값을 수정할 수 있다. 필요할 때마다 원본을 복제해서 사용하는 게  매번 필요한 상태 조합을 입력하여 수동적으로 초기화하는 것보다 더 편리할 수 있다.

프로토타입 패턴을 사용하지 않고 외부에서 복제를 실시할 수도 있다. 그러나 이 경우 해당 객체의 속성들에 직접 접근할 수 있기 때문에 캡슐화에 실패한 경우로 생각할 수 있다. 또한 이후 해당 클래스가 수정될 경우 외부 클래스의 코드까지 수정해야 하기 때문에 부적절하다.

public class Marine : Unit
{
    public int _hp;
    public int _damage;
	
    public Marine();
    public Marine(int hp, int damage)
    {
    	this._hp = hp;
        this._damage = damage;
    }
    public LooseHp(int damaged)
    {
    	this._hp -= damaged;
    }
    
}

public class MainTest
{
    public static int Main(string[] args)
    {
        Unit marineA = new Marin(40, 5);
        marineA.LooseHP(5);
        //외부 클래스에서 직접 마린 객체를 복제한다.
        //마린 객체의 속성에 직접 접근한다.
        Unit marineB = new Marine(marineA._hp, marineA._damage);
        //마린A : hp : 35, damage : 5
        //마린B : hp : 35, damage : 5
        return 0;
    }
}

또한 클래스에 접근 불가능한 속성이 있다면 완전한 복제에 성공할 수 없을 것이다.

public class Marine : Unit
{
    public int _hp;
    private int _damage;
	
    public Marine();
    public Marine(int hp, int damage)
    {
    	this._hp = hp;
        this._damage = damage;
    }
    public LooseHp(int damaged)
    {
    	this._hp -= damaged;
    }
    
}

public class MainTest
{
    public static int Main(string[] args)
    {
        Unit marineA = new Marin(40, 5);
        marineA.LooseHP(5);
        Unit marineB = new Marine(marineA._hp, marineA._damage); // Error! _damage에 직접 접근할 수 없다.

        return 0;
    }
}

프로토타입 패턴은 원본에서 직접 복제하여 복사본을 반환하기 때문에 모든 속성을 복제할 수 있고, 클라이언트에선 복제 함수만 호출하면 되기 때문에 결합도가 낮아진다.

public class Marine : Unit
{
    public int _hp;
    private int _damage;
	
    public Marine();
    public Marine(int hp, int damage)
    {
    	this._hp = hp;
        this._damage = damage;
    }
    public LooseHp(int damaged)
    {
    	this._hp -= damaged;
    }
    
    public Unit Clone()
    {
    	Unit clone = new Marine(_hp, _damage);
        return clone;
    }
    
}

public class MainTest
{
    public static int Main(string[] args)
    {
        Unit marineA = new Marin(40, 5);
        marineA.LooseHP(5);
        //원본이 직접 복제본을 만든다.
        Unit marineB = marineA.Clone();

        return 0;
    }
}

장점

  1. 객체를 만드는 과정을 숨길 수 있다.
  2. 객체에서 직접 복사본을 만들 수 있기 때문에 런타임 동안 새로운 객체를 추가하고 삭제할 수 있다.
  3. 클라이언트 코드와 객체의 결합도가 낮아진다.
  4. 복잡한 객체들을 더 쉽고 싸게 생성할 수 있다.
  5. 반환하는 객체를 추상적인 타입으로 반환할 수 있기 때문에 좀 더 유연한 객체를 생성할 수 있다.
  6. 팩토리 메서드를 사용하여 원본을 생성하는 것에 비해 서브 클래스의 수가 많이 줄어든다.

단점

  1. 복잡한 객체를 만드는 과정 자체가 복잡할 수 있다.(특히, 순환 참조)

참고자료

 

GoF의 디자인 패턴 - 예스24

이 책은 디자인 패턴을 다룬 이론서로 디자인 패턴의 기초적이고 전반적인 내용을 학습할 수 있다.

www.yes24.com

 

저작자표시 (새창열림)

'프로그래밍 이론 > 디자인 패턴' 카테고리의 다른 글

06. [Design Pattern] 어댑터(Adapter) 패턴  (0) 2023.11.21
05. [Design Pattern] 싱글톤(Singleton) 패턴  (0) 2023.11.16
03. [Design Pattern] 빌더(Builder) 패턴  (0) 2023.11.07
02. [Design Pattern] 추상 팩토리(Abstract Factory) 패턴  (0) 2023.10.27
01. [Design Pattern] 팩토리 메서드(Factory Method) 패턴  (0) 2023.10.27
  1. 프로토타입 패턴
  2. 구조
  3. 기본 인터페이스
  4. 왜 사용해야 할까?
  5. 장점
  6. 단점
  7. 참고자료
'프로그래밍 이론/디자인 패턴' 카테고리의 다른 글
  • 06. [Design Pattern] 어댑터(Adapter) 패턴
  • 05. [Design Pattern] 싱글톤(Singleton) 패턴
  • 03. [Design Pattern] 빌더(Builder) 패턴
  • 02. [Design Pattern] 추상 팩토리(Abstract Factory) 패턴
NewtronVania
NewtronVania
개발 내용과 지식을 정리한 블로그입니다.
NewtronVania
Newtron의 프로그래밍 블로그
NewtronVania
전체
오늘
어제
  • 분류 전체보기 (74)
    • 언리얼 (7)
      • 포트폴리오 (1)
    • 유니티 (2)
    • 코딩테스트 (27)
    • 프로그래밍 이론 (38)
      • 디자인 패턴 (25)
      • 알고리즘 (5)
      • 컴퓨터 그래픽스 (2)
      • AI (3)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 디자인 패턴
  • 유한 상태 머신
  • A* 알고리즘
  • 언리얼 오브젝트
  • UObject
  • 비트마스킹
  • Templet Method
  • 백준
  • Strategy
  • 다이나믹 프로그래밍
  • CS
  • q-learing
  • 행동 트리
  • Unreal
  • 강화학습
  • 게임 역사
  • 전략 패턴
  • daijkstra
  • 모션 워핑
  • 알고리즘
  • Algorithm
  • 게임 구현
  • DP
  • q-learning
  • 언리얼 엔진
  • 단어 검색
  • AI
  • 코딩테스트
  • behaviour tree
  • 루트 모션

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.1
NewtronVania
04. [Design Pattern] 프로토타입(Prototype) 패턴
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.