프로토타입 패턴

Prototype pattern

프로토타입 패턴은 소프트웨어 개발혁신적인 디자인 패턴입니다.생성할 개체 유형이 새 개체를 생성하기 위해 복제되는 프로토타입 인스턴스에 의해 결정될 때 사용됩니다.이 패턴은 공장에서의 메서드 패턴과 같이 클라이언트애플리케이션에서 오브젝트 작성자의 서브클래스를 회피하기 위해 사용되며, 특정 어플리케이션에서 비용이 너무 많이 드는 경우 표준적인 방법(를 들어 'new' 키워드 사용)으로 새로운 오브젝트를 작성하기 위한 고유 비용을 회피하기 위해 사용됩니다.

패턴을 구현하기 위해 클라이언트는 순수 가상 clone() 메서드를 지정하는 추상 기본 클래스를 선언합니다."polymorphic constructor" 기능이 필요한 클래스는 추상 기본 클래스에서 파생되어 clone() 연산을 구현합니다.

클라이언트는 하드 코드화된 클래스 이름에 "new" 연산자를 호출하는 코드를 쓰는 대신 프로토타입에서 clone() 메서드를 호출하거나 원하는 특정 구체적인 파생 클래스를 지정하는 매개 변수를 사용하여 공장 메서드를 호출하거나 다른 설계 패턴에 의해 제공되는 메커니즘을 통해 clone() 메서드를 호출합니다.

세포 분열은 두 개의 동일한 세포를 생성하며, 그 결과 자신을 복제하는 데 능동적인 역할을 하고 프로토타입 패턴을 보여주는 프로토타입의 한 예입니다.세포가 분열하면 유전자형이 같은 두 개의 세포가 생긴다.즉, 세포 자체가 [1]복제됩니다.

개요

프로토타입 설계 패턴은 반복적인 설계 문제를 해결하고 유연하고 재사용 가능한 객체 지향 소프트웨어, 즉 구현, 변경, 테스트 및 [2]: 117 재사용이 용이한 객체를 설계하는 방법을 설명하는 잘 알려진 23가지 GoF 설계 패턴 중 하나입니다.

프로토타입 디자인 패턴은 다음과 [3]같은 문제를 해결합니다.

  • 런타임에 생성할 개체를 지정하려면 어떻게 해야 합니까?
  • 동적으로 로드된 클래스를 인스턴스화하려면 어떻게 해야 합니까?

오브젝트를 필요로 하는(사용하는) 클래스 내에서 직접 오브젝트를 작성하는 것은 컴파일 시에 클래스를 특정 오브젝트에 커밋하고 런타임에 작성할 오브젝트를 지정할 수 없기 때문에 유연성이 떨어집니다.

프로토타입 설계 패턴은 이러한 문제를 해결하는 방법을 설명합니다.

  • 의 정의Prototype자신의 복사본을 반환하는 객체입니다.
  • 복사하여 새 개체를 만듭니다.Prototype물건.

이것에 의해, 다른 클래스의 설정이 가능하게 됩니다.Prototype새 개체를 만들기 위해 복사되는 개체 및 그 이상의 개체입니다.Prototype개체를 런타임에 추가하거나 제거할 수 있습니다.
아래 UML 클래스 및 시퀀스 다이어그램을 참조하십시오.

구조.

UML 클래스 및 시퀀스 다이어그램

프로토타입 설계 패턴에 대한 샘플 UML 클래스 및 시퀀스 다이어그램입니다.

위의 UML 클래스 다이어그램에서는Clientclass는Prototype복제용 인터페이스Product.그Product1class는 다음 명령을 실행합니다.Prototype인터페이스의 복사본을 만듭니다.
UML 시퀀스 다이어그램은 런타임 상호 작용을 보여 줍니다.Client오브젝트 콜clone()에서prototype:Product1오브젝트: 자신의 복사본을 만들고 반환합니다(a).product:Product1오브젝트)

UML 클래스 다이어그램

프로토타입 설계 패턴을 설명하는 UML 클래스 다이어그램

경험칙

때로는 크레디컬 패턴이 겹치기도 합니다.프로토타입 또는 추상 팩토리가 적절할 수도 있습니다.추상적 공장에서는 제품 개체를 복제하고 반환할 프로토타입 세트를 저장할 수도 있습니다.[2]: 126 추상 공장, 건설자 및 프로토타입은 [2]: 81, 134 구현에 싱글톤을 사용할 수 있습니다.추상 팩토리 클래스는 종종 팩토리 메서드(상속을 통한 생성)로 구현되지만 프로토타입(위임[2]: 95 통한 생성)을 사용하여 구현할 수 있습니다.

설계는 공장 출하 시 방법(복잡하지 않고 커스터마이즈 가능하며 서브클래스가 급증)을 사용하여 시작하여 설계자가 유연성이 [2]: 136 필요한 부분을 발견함에 따라 추상 공장, 프로토타입 또는 건설업체(더 유연하고 복잡함)로 발전하는 경우가 많습니다.

프로토타입에는 하위 분류가 필요하지 않지만 "초기화" 작업이 필요합니다.공장 출하시 방법에서는 서브클래싱이 [2]: 116 필요하지만 초기화가 필요하지 않습니다.

복합장식기 패턴을 많이 사용하는 디자인도 프로토타입의 이점을 누릴 수 있습니다.[2]: 126

실행 시 복제 중인 개체의 실제 복사본인 다른 개체를 작성하려면 개체를 복제()해야 하는 경우가 있습니다.True copy는 새로 생성된 개체의 모든 속성이 복제 중인 개체와 동일해야 함을 의미합니다.대신 new를 사용하여 클래스를 인스턴스화할 수 있는 경우 모든 속성을 초기 값으로 하는 개체를 얻을 수 있습니다.예를 들어, 은행 계정 트랜잭션을 수행하기 위한 시스템을 설계하는 경우 계정 정보를 보관하는 개체의 복사본을 만들고 해당 복사본에서 트랜잭션을 수행한 다음 수정된 개체로 원래 개체를 바꿀 수 있습니다.이 경우 new 대신 clone()을 사용합니다.

코드 샘플

유사 코드

텍스트에 대한 오카렌스 브라우저 클래스를 작성합시다.이 클래스는 텍스트에서 발생한 단어를 나열합니다.이러한 오브젝트는 발생장소를 찾는 데 비용이 많이 들기 때문에 작성하는 데 비용이 많이 듭니다.따라서 이러한 객체를 복제하기 위해 다음과 같은 프로토타입 패턴을 사용합니다.

class WordOccurrences is field occurrences 텍스트 내 각 단어 오카렌스 색인 목록입니다.생성자 WordOccurrences(텍스트, 워드)가 입력되었습니다. 오카렌스를 찾아야 하는 텍스트: 텍스트의 각 텍스트대한 오카렌스 목록 비우기 텍스트의 각 단어에 대해 Matchingg:= true입니다. 현재 단어가 문자일 경우 단어에 대한 색인입니다.r이 현재 텍스트 문자와 일치하지 않으면 isMatchingg:= false가 됩니다. isMatching이 true이면 현재 textIndex를 발생 목록 메서드에 추가합니다. getOneOccurrenceIndex(n)가 입력됩니다. 즉, n번째 발생을 가리킬 숫자입니다.output : n번째 오카렌스의 인덱스.method clone()이 출력된 경우 occurrences 필드의 n번째 항목(같은 데이터를 포함하는 WordOccurrences 개체)을 반환합니다.슈퍼 클래스의 clone()을 호출합니다.반환된 개체에서 [Occurrences]필드에 로컬오카렌스 필드의 값을 설정합니다.복제된 개체를 반환합니다. texte:= "프로토타입 패턴은 설계 패턴으로 처음 설명된 소프트웨어 개발의 회전 디자인 패턴입니다." wordw:= "pattern"d searchEnginen:= new WordOrcurrences(텍스트, word) anotherSearchEngineE:= searchEngine.clone()

(검색 알고리즘은 최적화되어 있지 않습니다.패턴 구현을 설명하기 위한 기본적인 알고리즘입니다.)

C#의 예

구체적인 유형의 객체는 프로토타입에서 생성됩니다.MemberwiseClone은 Clone 메서드에서 ConcreteFoo1 또는 ConcreteFoo2의 복사본을 만들고 반환하는 데 사용됩니다.

일반의 추상적인 학급 푸우 {     // 표준 구현      일반의 추상적인 푸우 클론(); }  일반의 학급 콘크리트 Foo1 : 푸우 {     일반의 덮어쓰다 푸우 클론()     {         돌아가다 (푸우)이것..멤버와이즈클론(); // 콘크리트 클래스를 복제합니다.     } }  일반의 학급 콘크리트 Foo2 : 푸우 {     일반의 덮어쓰다 푸우 클론()     {         돌아가다 (푸우)이것..멤버와이즈클론(); // 콘크리트 클래스를 복제합니다.     } } 

C++의 예

C++ 주석에서는 설계 패턴에 대한 설명과 다형 클래스 설계를 사용한 완전한 예시 구현에 대해 설명합니다.

Java의 예

이 패턴은 프로토타입을 사용하여 오브젝트 종류를 만듭니다.즉, 프로토타입 개체를 만드는 동안 클래스는 해당 개체의 복제본을 만들고 프로토타입으로 반환합니다.복제 방법은 필요할 때 프로토타입을 복제하는 데 사용되었습니다.

// 프로토타입 패턴 일반의 추상적인 학급 시제품 용구 복제 가능 {     일반의 시제품 클론() 던지다 지원되지 않는 클론예외.{         돌아가다 (시제품) 잘 하는 군요.클론();     } }   일반의 학급 콘크리트 프로토타입 1 확장 시제품 {     @오버라이드     일반의 시제품 클론() 던지다 지원되지 않는 클론예외. {         돌아가다 (콘크리트 프로토타입 1)잘 하는 군요.클론();     } }  일반의 학급 콘크리트 프로토타입 2 확장 시제품 {     @오버라이드     일반의 시제품 클론() 던지다 지원되지 않는 클론예외. {         돌아가다 (콘크리트 프로토타입 2)잘 하는 군요.클론();     } } 

PHP 예시

// PHP의 프로토타입 패턴은 내장된 PHP 함수 __clone()을 사용하여 수행됩니다.  추상적인 학급 시제품 {     일반의 스트링 $a;     일반의 스트링 b달러;          일반의 기능. 디스플레이 단점(): 무효     {         메아리치다 단점:{$ this->a}\n";         메아리치다 단점:{$ this->b}\n";     }          일반의 기능. 디스플레이 클론(): 무효     {         메아리치다 「클론:{$ this->a}\n";         메아리치다 「클론:{$ this->b}\n";     }      추상적인 기능. __클론(); }  학급 콘크리트 프로토타입 1 확장 시제품 {     일반의 기능. __개요()     {         $ this->a = 'A1';         $ this->b = 'B1';                  $ this->디스플레이 단점();     }      기능. __클론()     {         $ this->디스플레이 클론();     } }  학급 콘크리트 프로토타입 2 확장 시제품 {     일반의 기능. __개요()     {         $ this->a = 'A2';         $ this->b = 'B2';                  $ this->디스플레이 단점();     }      기능. __클론()     {         $ this->a = $ this->a .-C;         $ this->b = $ this->b .-C;                  $ this->디스플레이 클론();     } }  cP1달러 = 신규 콘크리트 프로토타입 1(); cP2달러 = 신규 콘크리트 프로토타입 2(); cP2C달러 = 클론 cP2달러;  // 결과: #quanton81  // 단점: A1 // 단점: B1 // 단점: A2 // 단점: B2 // CLON : A2-C // CLON : B2-C 

Python 예시

Python 버전 3.9 이상

수입품 알았다.  학급 시제품:     방어하다 클론(자신):         돌아가다 알았다..딥카피(자신)  한다면 __name__ == "_메인__":     시제품 = 시제품()     시제품_복사 = 시제품.클론()     인쇄물(시제품_복사) 

출력:

<_main__.0x7fae8f4e2940의 프로토타입 객체> 

「 」를 참조해 주세요.

레퍼런스

  1. ^ Duell, Michael (July 1997). "Non-Software Examples of Design Patterns". Object Magazine. 7 (5): 54. ISSN 1055-3614.
  2. ^ a b c d e f g Gamma, Erich; Helm, Richard; Johnson, Ralph; Vlissides, John (1994). Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley. ISBN 0-201-63361-2.
  3. ^ "The Prototype design pattern - Problem, Solution, and Applicability". w3sDesign.com. Retrieved 2017-08-17.