Рубрики
Uncategorized

Шаблон проектирования PHP (4) прототип модели пример прототипа детали

Автор оригинала: David Wong.

В этой статье описывается шаблон проектирования PHP: прототип прототипа шаблона. Для вашей справки приведем следующие сведения:

1. Обзор

Как мы все знаем, шаблон создания обычно используется для создания нового объекта, а затем мы используем этот объект для выполнения некоторых операций с объектом. Мы можем быстро создать объект с помощью шаблона прототипа и быстро завершить создание объекта без специальной операции new (). Это, несомненно, очень эффективный способ быстрого создания нового объекта.

Пример 1: король обезьян выщипывает волосы обезьяны и осторожно дует на них, чтобы сделать много Короля обезьян.

Пример 2: отправьте его экспресс-почтой

Вот сценарий почтового экспресса: “Пришлите мне экспресс.” – сказал клиент. “Куда? Чтобы… ” – спрашиваешь Ты. “Это почти то же самое, что и в прошлый раз. Это просто отправлено по почте на другой адрес. Вот почтовый адрес…” Клиент говорит и дает вам записку с почтовым адресом. “Хорошо!” Вы с радостью соглашаетесь, что, поскольку вы сохранили предыдущую почтовую информацию пользователя, вы можете быстро создавать новые экспресс-данные, просто скопировав данные, а затем просто изменив их.

2. Проблемы

Когда конструктор объекта очень сложен, для создания нового объекта требуется много времени и ресурсов? Как мы его создаем?

3. Решения

Создайте больше объектов одного и того же типа, скопировав (клонировав, скопировав) объект указанного типа. Этот указанный объект можно назвать объектом “прототип”, то есть путем копирования объекта-прототипа, чтобы получить больше объектов того же типа. Шаблон проектирования прототипа. Многие библиотеки шаблонов в PHP используют клонирование. Такие, как Смарти.

4. Применимость

Основная идея шаблона прототипа состоит в том, чтобы клонировать новый объект на основе существующего объекта. Как правило, внутри объекта предоставляется метод клонирования, и с помощью этого метода возвращается копия объекта. Этот способ создания объекта отличается от предыдущих шаблонов создания. Фабричный шаблон и абстрактная фабрика, описанные выше, являются фабрикой, инкапсулированной в процессе новой операции тела, возвращающей новый объект. Иногда не стоит создавать объект с помощью такой фабрики создания. Особенно в следующих сценариях может быть проще и эффективнее использовать режим прототипа.

Когда система должна быть независимой от создания, состава и представления продукта, следует использовать режим прототипа

2) когда класс, который должен быть создан, указан во время выполнения, например, при динамической загрузке;

3) во избежание создания уровня заводского класса, параллельного уровню класса продукта

Когда экземпляр класса может иметь только одно из нескольких различных сочетаний состояний. Возможно, будет удобнее создать соответствующее количество прототипов и клонировать их, чем каждый раз создавать экземпляр класса вручную с соответствующим состоянием. (то есть, когда мы имеем дело с некоторыми относительно простыми объектами, и разница между объектами очень мала, возможно, различаются только несколько фиксированных атрибутов, возможно, мы используем шаблон прототипа более подходящим образом).

5. Структура

Структура прототипа шаблона показана на рисунке выше на следующей странице:

6. Состав

Роль клиента: клиентская программа, использующая объекты-прототипы Роль абстрактного прототипа: Определяет интерфейс, который должен реализовывать конкретный объект-прототип (если вы хотите обеспечить глубокое копирование, у вас должно быть правило реализации клонирования) Конкретный прототип: производный от абстрактного прототипа, это объект, используемый клиентской программой, то есть скопированный объект. Эта роль должна реализовать интерфейс, необходимый для роли абстрактного прототипа.

7. Эффект

Шаблон прототипа имеет многие из тех же эффектов, что и шаблоны абстрактных фабрик и построителей: он скрывает от клиентов определенные классы продуктов, тем самым уменьшая количество известных клиентам имен. Кроме того, эти шаблоны позволяют клиентам использовать классы для конкретных приложений без их изменения.

Вот некоторые другие преимущества режима прототипа.

1) добавление и удаление продуктов во время выполнения: прототип позволяет включать в систему новый конкретный класс продуктов только путем регистрации экземпляров прототипов у клиентов. Он более гибкий, чем другие творческие шаблоны, поскольку клиенты могут создавать и удалять прототипы во время выполнения. 2) изменение значений для указания новых объектов: высокодинамичные системы позволяют определять новое поведение с помощью композиции объектов – например, путем указания значений для переменной объекта – без определения новых классов. Вы можете эффективно определять новые объекты класса, создавая экземпляры существующих классов и регистрируя их в качестве прототипов клиентских объектов. Клиент может делегировать ответственность прототипу, чтобы показать новое поведение. Этот дизайн позволяет пользователям определять новые “классы” без программирования. На самом деле клонирование прототипа похоже на создание экземпляра класса. Шаблон прототипа может значительно сократить количество классов, требуемых системой. 3) Измените структуру, чтобы указать новые объекты: много

Основным недостатком прототипа является то, что каждый подкласс прототипа должен реализовывать операцию клонирования, что может быть затруднительно. Например, трудно добавить операции клонирования, когда рассматриваемый класс уже существует. Клонирование также может быть затруднено, если вы включаете объекты, которые не поддерживают копирование или имеют циклические ссылки.

8. Реализация

php
/**
 *Prototype pattern 
 */
 
/**
 *Abstract archetypal roles
 */
interface Prototype {
  public function copy();
}
 
/**
 *Specific archetypal roles
 */
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;
  }
 
  public function copy() {
    /**Deep copy*/
    return clone $this;  
    /**Light copy*/
    //return $this;  
  }
}
 
class Client {
 
   /**
   * Main program.
   */
  public static function main() {
    $object1 = new ConcretePrototype(11);
    $object_copy = $object1->copy();
 
    var_dump($object1->getName());
    echo '
'; var_dump($object_copy->getName()); echo '
'; $object1->setName(22); var_dump($object1->getName()); echo '
'; var_dump($object_copy->getName()); echo '
'; } } Client::main(); ?>

9. Мелкая копия и глубокая копия

Принципиальная схема прототипа шаблона:

Легкая копия

Все переменные скопированного объекта имеют те же значения, что и исходный объект, и ссылки на другие объекты по-прежнему указывают на исходный объект. Другими словами, он не копирует текущий объект.

Объекты после неглубокой репликации и копирования объектов:

Глубокое копирование

Все переменные скопированного объекта имеют те же значения, что и исходный объект, за исключением тех, которые относятся к другим объектам. Переменные, которые ссылаются на другие объекты, будут указывать на новый скопированный объект вместо исходного объекта, на который имеется ссылка. Другими словами, глубокое копирование копирует все объекты, на которые ссылается объект, подлежащий копированию один раз, и этот вид копирования объекта, на который ссылается ссылка, называется косвенным копированием.

Глубоко реплицированные объекты и копии объектов:

Сколько слоев глубокой копии должно пройти-вопрос неопределенный.

Когда вы решаете скопировать объект в режиме глубокого копирования, вы должны решить, делать ли неглубокую копию или глубокую копию, или продолжать использовать глубокую копию для косвенно скопированного объекта.

Поэтому, делая глубокую копию, вам нужно решить, насколько она глубока. Кроме того, в процессе глубокого копирования, вероятно, возникнет проблема круговой ссылки.

10. Прототип модели с менеджером прототипов

Вторая форма шаблона прототипа – это шаблон прототипа с менеджером прототипов. Его UML-диаграмма выглядит следующим образом:

Роль менеджера прототипов: создание конкретных объектов класса прототипов и запись каждого созданного объекта.

В следующем примере показано, что пользовательский прототип цвета хранится в диспетчере прототипов, и клиент клонирует объект цвета через диспетчер прототипов.

red = $red;
  $this->green = $green;
  $this->blue = $red;
 }
 /**
  * set red
  *
  * @param unknown_type $red
  */
 public function setRed($red) {
  $this->red = $red;
 }
 
 /**
  * get red
  *
  */
 public function getRed(){
  return $this->red;
 }
 /**
  *set Green
  *
  * @param $green
  */
 public function setGreen($green) {
  $this->green = $green;
 }
 /**
  * get Green
  *
  * @return unknown
  */
 public function getGreen() {
  return $this->green ;
 }
 /**
  *set Blue
  *
  * @param $Blue
   */
 public function setBlue($Blue) {
  $this->blue = $Blue;
 }
 /**
  * get Blue
  *
  * @return unknown
  */
 public function getBlue() {
  return $this->blue ;
 }
 
 /**
 * Enter description here...
 *
 * @return unknown
 */
 function copy(){
 return clone $this;
 }
 
 function display() {
 echo $this->red , ',', $this->green, ',', $this->blue ,'
'; } } /** * Enter description here... * */ class ColorManager { // Fields static $colors = array(); // Indexers public static function add($name, $value){ self::$colors[$name] = $value; } public static function getCopy($name) { return self::$colors[$name]->copy(); } } /** *Client * */ class Client { public static function Main() { //Prototype: white ColorManager::add("white", new Color( 255, 0, 0 )); //The red color can be obtained from the prototype white object, but the white is modified: R $red = ColorManager::getCopy('white'); $red->setRed(255); $red->display(); //Green can be obtained from the prototype white object, but the White: G $green = ColorManager::getCopy('white'); $green->setGreen(255); $green->display(); //The green can be obtained from the prototype white object, but the white is modified: B $Blue = ColorManager::getCopy('white'); $Blue->setBlue(255); $Blue->display(); } } ini_set('display_errors', 'On'); error_reporting(E_ALL & ~ E_DEPRECATED); Client::Main(); ?>

Подробнее о содержании, связанном с PHP заинтересованные читатели могут ознакомиться с этой темой сайта: “Вводный учебник по объектно-ориентированному программированию PHP”, “Навыки работы с массивом PHP (массив)”, “Вводный курс по основному синтаксису PHP”, “Краткое описание операций PHP и использования операторов”, “Краткое описание использования символьной строки (строки) PHP”, “Руководство по вводу в работу с базой данных PHP + MySQL” и “Общая работа с базой данных PHP” Краткое описание навыков написания

Я надеюсь, что эта статья поможет вам в программировании на PHP.