development:software-architecture:design-patterns:prototype
Prototype
Giả sử bạn có một đối tượng và bạn muốn tạo một bản sao chính xác của nó. Bạn sẽ làm điều này như thế nào? Đầu tiên, bạn phải tạo một đối tượng mới của cùng một lớp. Sau đó, bạn phải đi qua tất cả các trường của đối tượng ban đầu và sao chép giá trị của chúng sang đối tượng mới.
Tuy nhiên không phải tất cả các đối tượng đều có thể được sao chép theo cách đó vì một số trường đối tượng có thể là private và không thể get từ bên ngoài đối tượng.
- Page.php
<?php namespace OneSite\DesignPattern\Prototype; /** * Prototype. */ class Page { private $title; private $body; /** * @var Author */ private $author; private $comments = []; /** * @var \DateTime */ private $date; // +100 private fields. public function __construct(string $title, string $body, Author $author) { $this->title = $title; $this->body = $body; $this->author = $author; $this->author->addToPage($this); $this->date = new \DateTime; } public function addComment(string $comment): void { $this->comments[] = $comment; } /** * You can control what data you want to carry over to the cloned object. * * For instance, when a page is cloned: * - It gets a new "Copy of ..." title. * - The author of the page remains the same. Therefore we leave the * reference to the existing object while adding the cloned page to the list * of the author's pages. * - We don't carry over the comments from the old page. * - We also attach a new date object to the page. */ public function __clone() { $this->title = "Copy of " . $this->title; $this->author->addToPage($this); $this->comments = []; $this->date = new \DateTime; } }
- Author.php
<?php namespace OneSite\DesignPattern\Prototype; class Author { private $name; /** * @var Page[] */ private $pages = []; public function __construct(string $name) { $this->name = $name; } public function addToPage(Page $page): void { $this->pages[] = $page; } }
- PrototypeTest.php
<?php namespace OneSite\DesignPattern\Tests; use OneSite\DesignPattern\Prototype\Author; use OneSite\DesignPattern\Prototype\Page; use PHPUnit\Framework\TestCase; class PrototypeTest extends TestCase { /** * */ public function testBuilderPattern() { $author = new Author("John Smith"); $page = new Page("Tip of the day", "Keep calm and carry on.", $author); // ... $page->addComment("Nice tip, thanks!"); // ... $draft = clone $page; echo "\n\nDump of the clone. Note that the author is now referencing two objects."; print_r($draft); return $this->assertTrue(true); } }
development/software-architecture/design-patterns/prototype.txt · Last modified: 2024/08/14 13:44 by tungnt