Concept
프로토타입 인스턴스를 사용하여 생성할 객체의 유형을 지정하고, 이러한 프로토타입을 복사하여 새로운 객체를 생성합니다.
프로토타입 프로토타입 패턴은 창의적인 디자인 패턴입니다. 프로토타입 패턴을 사용하면 생성 방법에 대한 세부 정보 없이도 하나의 객체가 다른 사용자 정의 가능한 객체를 만들 수 있습니다.
작동 원리
생성할 객체에 프로토타입 객체를 전달하여 프로토타입 객체에 자신을 복사하도록 요청하여 생성할 객체를 생성합니다.
어떤 문제를 해결합니까
그것이 직면한 주요 문제는 요구 사항의 변화로 인해 "복잡한 구조를 가진 일부 개체"가 생성된다는 것입니다. 이러한 개체는 종종 급격한 변화에 직면하지만 비교적 안정적이고 일관된 인터페이스를 가지고 있습니다.
역할
추상 프로토타입(Prototype) 역할: 자신을 복제하는 인터페이스를 선언
콘크리트 프로토타입(Concrete Prototype) 역할: 자신을 복제하는 연산을 구현
구조도
코드
얕은 복사 모드
소스 객체의 참조 주소 복사 등 직접 복사, 따라서 원본 콘텐츠가 변경되고 새로운 콘텐츠가 변경됩니다.
<?php header('Content-type:text/html;charset=utf-8'); /** * PHP原型模式-潜拷贝 */ /** * Interface Prototype 抽象原型模式 */ interface Prototype { // 定义拷贝自身方法啊 public function copy(); } /** * Class ConcretePrototype 具体原型模式 */ class ConcretePrototype implements Prototype { private $name; public function __construct($name) { $this->name = $name; } public function setName($name) { $this->name=$name; } public function getName() { return $this->name; } /** * 拷贝自身 * * @return ConcretePrototype 返回自身 */ public function copy() { return clone $this;//浅拷贝 } } /** * 测试潜拷贝 */ class LatentCopyDemo{ public $array; } /** * Class Client 客户端 */ class Client{ /** * 测试方法 */ public static function test(){ $demo = new LatentCopyDemo(); $demo->array = array(1,2); $object1 = new ConcretePrototype($demo); $object2 = $object1->copy(); var_dump($object1->getName()); echo '<br/>'; var_dump($object2->getName()); echo '<br/>'; $demo->array = array(3, 4); var_dump($object1->getName()); echo '<br />'; var_dump($object2->getName()); echo '<br />'; } } Client::test();
실행 결과
object(LatentCopyDemo)#1 (1) { ["array"]=> array(2) { [0]=> int(1) [1]=> int(2) } } object(LatentCopyDemo)#1 (1) { ["array"]=> array(2) { [0]=> int(1) [1]=> int(2) } } object(LatentCopyDemo)#1 (1) { ["array"]=> array(2) { [0]=> int(3) [1]=> int(4) } } object(LatentCopyDemo)#1 (1) { ["array"]=> array(2) { [0]=> int(3) [1]=> int(4) } }
Deep Copy 모드
Deep Copy는 직렬화와 역직렬화를 통해 복사본을 완성하고, 새 복사본의 내용은 원본을 완전히 복사합니다. 콘텐츠 . 원본 콘텐츠는 변경되지만 새 콘텐츠는 변경되지 않습니다.
<?php header('Content-type:text/html;charset=utf-8'); /** * PHP原型模式-深拷贝 */ /** * Interface Prototype 抽象原型模式 */ interface Prototype { // 定义拷贝自身方法啊 public function copy(); } /** * Class ConcretePrototype 具体原型模式 */ class ConcretePrototype implements Prototype { private $name; public function __construct($name) { $this->name = $name; } public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } /** * 拷贝自身 * * @return ConcretePrototype 返回自身 */ public function copy() { $serialize_obj = serialize($this); $clone_obj = unserialize($serialize_obj); return $clone_obj; } } /** * 测试潜拷贝 */ class DeepCopyDemo{ public $array; } /** * Class Client 客户端 */ class Client{ /** * 测试方法 */ public static function test(){ $demo = new DeepCopyDemo(); $demo->array = array(1,2); $object1 = new ConcretePrototype($demo); $object2 = $object1->copy(); var_dump($object1->getName()); echo '<br/>'; var_dump($object2->getName()); echo '<br/>'; $demo->array = array(3, 4); var_dump($object1->getName()); echo '<br />'; var_dump($object2->getName()); echo '<br />'; } } Client::test();
운영결과
object(DeepCopyDemo)#1 (1) { ["array"]=> array(2) { [0]=> int(1) [1]=> int(2) } } object(DeepCopyDemo)#4 (1) { ["array"]=> array(2) { [0]=> int(1) [1]=> int(2) } } object(DeepCopyDemo)#1 (1) { ["array"]=> array(2) { [0]=> int(3) [1]=> int(4) } } object(DeepCopyDemo)#4 (1) { ["array"]=> array(2) { [0]=> int(1) [1]=> int(2) } }
장점과 단점
장점
1. 런타임 시 제품 추가 및 삭제 가능
2. 새로운 객체 지정을 위해 값 변경 가능
3. 새로운 객체 지정을 위한 구조 변경 가능
4. 하위 클래스 구성 감소
5. 클래스를 사용하여 애플리케이션을 동적으로 구성
단점
프로토타입 패턴의 가장 큰 단점은 각 클래스에 복제 방법이 탑재되어야 한다는 것입니다. 게다가 이 복제 방법은 클래스의 기능에 대한 포괄적인 고려가 필요합니다. 이는 새로운 클래스의 경우 어렵지 않지만 기존 클래스를 변형하는 것은 반드시 쉬운 일이 아닙니다.
적용 가능한 시나리오
제품과 독립적으로 시스템을 생성, 구성, 표현해야 하는 경우 프로토타입 패턴을 사용합니다.
인스턴스화할 클래스가 런타임에 지정되는 경우, 클래스의 인스턴스가 여러 가지 상태 조합 시간 중 하나만 가질 수 있는 경우 제품 클래스 계층
과 동일한 팩토리 클래스 계층 구조를 생성하지 않으려면 동적 로드
등을 사용합니다. 매번 적절한 상태로 클래스를 수동으로 인스턴스화하는 것보다 해당 수의 프로토타입을 생성하고 복제하는 것이 더 편리할 수 있습니다