Home Backend Development PHP Tutorial PHP prototype pattern case analysis

PHP prototype pattern case analysis

May 17, 2018 am 11:42 AM
php Case parse

This time I will bring you a case analysis of PHP prototype mode. What are the precautions when using PHP prototype mode? The following is a practical case, let's take a look.

The Prototype Design Pattern is interesting because it uses a cloning technique to copy instantiated objects. New objects are created by copying prototype instances. Here, the instances are batch instances The purpose of the prototype design pattern is to reduce the overhead of instantiating objects by using clones. Instead of instantiating new objects from a class, you can use a clone of an existing instance.

Clone function

The key to using the prototyping pattern in PHP is to understand how to use the built-in functionclone().

<?php
abstract class CloneObject
{
  public $name;
  public $picture;
  abstract function clone();
}
class Boy extends CloneObject
{
  public function construct()
  {
    $this->face = "handsome";
    $this->name = "chenqionghe";
  }
  public function display()
  {
    echo &#39;look : &#39;.$this->face;;
    echo &#39;<br />&#39;.$this->name.&#39;<br />&#39;;
  }
  public function clone() {}
}
$boy = new Boy();
$boy->display();
$cloneBoy = clone $boy;
$cloneBoy->face = "still handsome";
$cloneBoy->display();
Copy after login

The running results are as follows

look : handsome
chenqionghe
look : still handsome
chenqionghe

$cloneBoy instance is cloned An instance of Boy, $boy, can access the same properties as $boy, and can change these properties like a direct instance of the Boy class.

Note: For cloned instances, clone keyword will instantiate another instance of the class for that instance (using the clone keyword can create a copy of the class, and if possible, the object's clone method will be automatically called, but the object's ## cannot be called directly #clone method), regarding the process, one thing to note is that cloning will not start the action in the constructor.

Simple Prototype example

Let’s take the study of fruit flies as an example. The goal of the research is to establish a prototype fruit fly, and then once a mutation occurs, build this mutant fruit fly

Abstract class interface and concrete implementation

The two concrete class implementations of the prototype (IPrototype) respectively represent different genders of fruit flies, including gender variables (gender) and different genders and behavior.

IPrototype.php

<?php
abstract class IPrototype
{
  public $eyeColor;
  public $winBeat;
  public $unitEypes;
  abstract function clone();
}
Copy after login

The difference between the two implementations of IPrototype is reflected in gender. Gender is identified by constants, one is MALE and the other is FEMAIL. The male fruit fly has a $mated Boolean variable. After the male fruit fly mates, this Boolean variable will be set to true. The female fruit fly has a $fecundity variable, which contains a numeric value indicating the reproductive ability of the male fruit fly. (Number of eggs laid):

MaleProto.php

<?php
include_once(&#39;IPrototype.php&#39;);
class MaleProto extends IPrototype
{
  const gender = "MALE";
  public $mated;
  public function construct()
  {
    $this->eyeColor = "red";
    $this->winBeat = "220";
    $this->unitEypes = "760";
  }
  public function clone(){}
}
Copy after login

FemaleProto.php

<?php
include_once(&#39;IPrototype.php&#39;);
class FemaleProto extends IPrototype
{
  const gender = "FEMAIL";
  public $fecundity;
  public function construct()
  {
    $this->eyeColor = "red";
    $this->winBeat = "220";
    $this->unitEypes = "760";
  }
  public function clone(){}
}
Copy after login

customer

In the prototyping design pattern, the Client class is indeed an indispensable part. The reason is that although the concrete implementation of the subclass is used as the template for the instance, the specific work of cloning the instance using the same template is The

Client.php

<?php
function autoload($class_name)
{
  include_once $class_name.&#39;.php&#39;;
}
class Client
{
  //用于直接实例化
  private $fly1;
  private $fly2;
  //用于克隆
  private $c1Fly;
  private $c2Fly;
  private $updatedCloneFly;
  public function construct()
  {
    //实例化
    $this->fly1 = new MaleProto();
    $this->fly2 = new FemaleProto();
    //克隆
    $this->c1Fly = clone $this->fly1;
    $this->c2Fly = clone $this->fly2;
    $this->updatedCloneFly = clone $this->fly2;
    //更新克隆
    $this->c1Fly->mated = "true";
    $this->c2Fly->fecundity = &#39;186&#39;;
    $this->updatedCloneFly->eyeColor = "purple";
    $this->updatedCloneFly->winBeat = "220";
    $this->updatedCloneFly->unitEyes = &#39;750&#39;;
    $this->updatedCloneFly->fecundity = &#39;92&#39;;
    //通过类型提示方法发送
    $this->showFly($this->c1Fly);
    $this->showFly($this->c2Fly);
    $this->showFly($this->updatedCloneFly);
  }
  private function showFly(IPrototype $fly)
  {
    echo "Eye color: ".$fly->eyeColor."<br />";
    echo "Wing Beats/second: ".$fly->winBeat."<br />";
    echo "Eye units: ".$fly->unitEypes."<br />";
    $genderNow = $fly::gender;
    echo "Gender: ".$genderNow."<br />";
    if($genderNow == "FEMAIL")
    {
      echo "Number of eggs: ".$fly->fecundity."<hr />";
    }
    else
    {
      echo "Mated: ".$fly->mated."<hr />";
    }
  }
}
$worker = new Client();
Copy after login

completed by the Client class runs as follows

Eye color: red

Wing Beats/second : 220
Eye units: 760
Gender: MALE
Mated: trueEye color: red
Wing Beats/second: 220
Eye units: 760
Gender: FEMAIL
Number of eggs: 186Eye color: purple
Wing Beats/second: 220
Eye units: 760
Gender: FEMAIL
Number of eggs: 92

Prototype mode depends on The customer uses the concrete prototype through the cloning process. In this design process, the customer is a participant who completes the cloning. Since cloning is a key element in prototype design, the customer is a basic participant, not just a requesting class.

Modern Enterprise Organization

In terms of creative design patterns, modern enterprise organizations are very suitable for prototype implementation. Nowadays, enterprise organizations often have complex and huge hierarchical structures, such as Like object-oriented programming, many common characteristics need to be modeled. Now describe a software engineering company through an example.

A software engineering company is a typical modern organization. The Engineering Department is responsible for creating products, managing The Management department handles the coordination and organization of resources, and the Marketing department is responsible for the sales, promotion and overall marketing of products.

Encapsulation in the interface

在这个原型实现中,首先为程序的接口(一个抽象类)增加OOP,与所有原型接口一样,这个接口包含一个克隆操作.另外它还包含一些抽象和具体的获取方法和设置方法.其中有一个抽象获取方法/设置方法对,但要由3个具体原型实现为这个抽象获取方法/设置方法对提供具体实现.其他获取方法和设置方法分分别应用于员工名,ID码和照片等属性.注意所有这些属性都是保护属性(protected),所以尽管具体的获取方法和设置方法有公共可见性,但由于操作中使用的属性具有保护和可见性,这就提供了某种程度的封装:

<?php
abstract class IAcmePrototype
{
  protected $name;
  protected $id;
  protected $employeePic;
  protected $department;
  //部门
  abstract function setDept($orgCode);
  abstract function getDept();
  //名字
  public function setName($emName)
  {
    $this->name = $emName;
  }
  public function getName()
  {
    return $this->name;
  }
  //ID
  public function setId($emId)
  {
    $this->id = $emId;
  }
  public function getId()
  {
    return $this->id;
  }
  //雇员图像
  public function setPic($ePic)
  {
    $this->employeePic = $ePic;
  }
  public function getPic()
  {
    return $this->employeePic;
  }
  abstract function clone();
}
Copy after login

利用这些获取方法和设置方法, 所有属性的值都通过继承的保护变量来设置.采用这种设计, 扩展类及其实例可以得到更好的封装.

接口实现

3个IAcmePrototype子类都必须实现"dept"抽象方法以及clone()方法.类似地, 每个具体原型类还包含一个常量UNIT,它提供一个赋值,可以由实例(包括克隆的对象)作为标识

首先来看市场部的Marketing类:

Marketing.php

<?php
include_once(&#39;IAcmePrototype.php&#39;);
class Marketing extends IAcmePrototype
{
  const UNIT = "Marketing";
  private $sales = "sales";
  private $promotion = "promotion";
  private $strategic = "strategic planning";
  public function setDept($orgCode)
  {
    switch($orgCode)
    {
      case 101:
        $this->department = $this->sales;
        break;
      case 102:
        $this->department = $this->promotion;
        break;
      case 103:
        $this->department = $this->strategic;
        break;
      default :
        $this->department = "未识别的市场部";
    }
  }
  public function getDept()
  {
    return $this->department;
  }
  public function clone() {}
}
Copy after login

setDept()方法的实现使用了一个参数.并不是直接输入市场部的部门,这个方法的参数是一个数字码, 通过一个switch语句,限制了3种可接受的情况和默认情况,别外两个原型实现也类似

Management.php

<?php
include_once(&#39;IAcmePrototype.php&#39;);
class Management extends IAcmePrototype
{
  const UNIT = "Management";
  private $research = "research";
  private $plan = "planning";
  private $operations = "operations";
  public function setDept($orgCode)
  {
    switch($orgCode)
    {
      case 201:
        $this->department = $this->research;
        break;
      case 202:
        $this->department = $this->plan;
        break;
      case 203:
        $this->department = $this->operations;
        break;
      default :
        $this->department = "未识别的管理部";
    }
  }
  public function getDept()
  {
    return $this->department;
  }
  public function clone() {}
}
Copy after login

Engineering.php

<?php
include_once(&#39;IAcmePrototype.php&#39;);
class Engineering extends IAcmePrototype
{
  const UNIT = "Engineering";
  private $development = "development";
  private $design = "design";
  private $sysAd = "system administration";
  public function setDept($orgCode)
  {
    switch($orgCode)
    {
      case 301:
        $this->department = $this->development;
        break;
      case 302:
        $this->department = $this->design;
        break;
      case 303:
        $this->department = $this->sysAd;
        break;
      default :
        $this->department = "未识别的工程部";
    }
  }
  public function getDept()
  {
    return $this->department;
  }
  public function clone() {}
}
Copy after login

以上这3个具体原型实现分别有其特定用途,不过它们都符合接口,可以创建各个原型实现的一个实例, 然后根据需要克隆多个实例.这个克隆的工作由Client类完成

客户

客户的设置非常简单: 分别创建各个具体原型的一个实例, 然后按以下列表来克隆各个实例:

市场部门实例:
-----市场部门克隆
-----市场部门克隆
管理部门实例
-----管理部门克隆
工程部门实例
-----工程部门克隆
-----工程部门克隆

将来只使用这些克隆对象.使用获取方法和设置方法将各个特定情况的信息赋给这些克隆对象.以下是Client的实现

Client.php

<?php
function autoload($class_name)
{
  include_once $class_name.&#39;.php&#39;;
}
class Client
{
  private $market;
  private $manage;
  private $engineer;
  public function construct()
  {
    $this->makeConProto();
    $Tess = clone $this->market;
    $this->setEmployee($Tess, "Tess Smith" , 101, &#39;ts101-1234&#39;, &#39;tess.png&#39;);
    $this->showEmployee($Tess);
    $Jacob = clone $this->market;
    $this->setEmployee($Jacob, "Jacob Jones" , 101, &#39;jj101-2234&#39;, &#39;jacob.png&#39;);
    $this->showEmployee($Jacob);
    $Ricky = clone $this->manage;
    $this->setEmployee($Ricky, "Ricky Rodriguez" , 203, &#39;rr101-5634&#39;, &#39;ricky.png&#39;);
    $this->showEmployee($Ricky);
    $Olivaia = clone $this->engineer;
    $this->setEmployee($Olivaia, "Olivaia Perez" , 302, &#39;op301-1278&#39;, &#39;olivia.png&#39;);
    $this->showEmployee($Olivaia);
    $John = clone $this->engineer;
    $this->setEmployee($John, "John Jacson" , 101, &#39;jj301-14548&#39;, &#39;john.png&#39;);
    $this->showEmployee($John);
  }
  private function makeConProto()
  {
    $this->market = new Marketing();
    $this->manage = new Management();
    $this->engineer = new Engineering();
  }
  private function showEmployee(IAcmePrototype $employeeNow)
  {
    $px = $employeeNow->getPic();
    echo "<img src=$px width=&#39;150&#39; height=&#39;150&#39; /><br />";
    echo $employeeNow->getName().&#39;<br />&#39;;
    echo $employeeNow->getDept().&#39;:&#39;.$employeeNow::UNIT.&#39;<br />&#39;;
    echo $employeeNow->getId().&#39;<hr />&#39;;
  }
  private function setEmployee(IAcmePrototype $employeeNow, $nm, $dp, $id, $px)
  {
    $employeeNow->setName($nm);
    $employeeNow->setDept($dp);
    $employeeNow->setId($id);
    $employeeNow->setPic($px);
  }
}
$worker = new Client();
Copy after login

解释:

客户Client的构造函数类包含3个私有属性, 用来分别实例化3个具体原型类. makeConPro()方法生成必要的实例.

接下来,使用克隆技术创建一个"员工"实例.然后,这个实例向一个设置方法setEmployee()发送特定的实例信息,这个设置方法使用IAcmePrototype接口类型提示,不过需要说明, 它只对第一个参数使用类型提示,其他参数都没有类型提示, 并不要求它们派生自IAcmePrototype接口.克隆"员工"可以使用IAcmePrototype抽象类的所有设置方法以及具体原型类实现的setDept()方法.

要使用各个员工的数据,Client类可以使用继承的获取方法.以下是运行Client输出的结果

Tess Smith
sales:Marketing
ts101-1234
Jacob Jones
sales:Marketing
jj101-2234
Ricky Rodriguez
operations:Management
rr101-5634
Olivaia Perez
design:Engineering
op301-1278
John Jacson
未识别的工程部:Engineering
jj301-14548

可以根据需要增加更多的克隆, 而且只需要对具体原型类完成一次实例化.使用原型模式时, 并不是建立具体类的多个实例,而只需要一个类实例化和多个克隆.

完成修改,增加特性

要记住,最重要(可能也是最基本)的是, 设计模式允许开发人员修改和增补程序,而不必一切从头开始.例如, 假设总裁决定公司增加一个新的部门,比如研究部门(Research), 这会很难吗?一点也不难.Research可以扩展IAcmePrototype抽象类, 然后实现抽象获取方法和设置方法来反映这个研究部门的组织.需要说明,Client类中获取方法和设置方法使用的代码提示指示一个接口,而不是一个抽象类的具体实现.所以, 只要增加的单元正确地实现了这个接口,就能顺利地增加到应用中, 而不会带来波动,也不需要对程序中的其他参与者进行重构.

Not only can more concrete classes be added, but individual classes can be easily modified without causing disruption. For example, suppose the marketing department of this organization decides that, in addition to their existing departments, they need a special The online marketing department. As a result, the switch/case operation requires a new branch (case) and a new private attribute (variable) to describe the new department. This change will be frozen in a separate class , without affecting other participants. Since this change will not cause damage, the larger the scale of the application, the more important this is. It can be seen that the prototyping design pattern not only supports consistency, but also supports flexible changes.

Prototypes in the PHP world

Since PHP is a server-side language and an important tool for interacting with MySQL database, prototyping is Patterns are particularly useful here. Instead of creating separate objects for the first element in the database, PHP can use the Prototype pattern to create an instance of a concrete class and then clone the remaining instances (records) using the data in the database.

Understand After the cloning process, compared to the process of direct instantiation, you may ask: "What is the difference?" In other words, why does cloning require fewer resources than directly instantiating the object? The difference is not directly visible. When an object is instanced through cloning, it does not start a constructor. The clone gets all the properties of the original class, even those of the parent interface, and also inherits all the values ​​passed to the instantiated object. All values ​​generated by the constructor and the values ​​stored in the object properties will become part of the cloned object. Therefore, there is no return constructor. If you find that your cloned object really needs to access the values ​​generated by the constructor but cannot access them, this indicates that the class needs to be refactored so that Instances can have all the information they need, and can pass this data to cloned objects.

In general, the prototype pattern is very suitable for many different types of PHP projects. If solving a problem requires even Both the creational mode and the prototype mode can be used.

I believe you have mastered the method after reading the case in this article. For more exciting information, please pay attention to other related articles on the PHP Chinese website!

Recommended reading:

PHP Closure Principle (OCP) use case analysis

Detailed explanation of PHP dependency inversion case

The above is the detailed content of PHP prototype pattern case analysis. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

PHP 8.4 Installation and Upgrade guide for Ubuntu and Debian PHP 8.4 Installation and Upgrade guide for Ubuntu and Debian Dec 24, 2024 pm 04:42 PM

PHP 8.4 brings several new features, security improvements, and performance improvements with healthy amounts of feature deprecations and removals. This guide explains how to install PHP 8.4 or upgrade to PHP 8.4 on Ubuntu, Debian, or their derivati

7 PHP Functions I Regret I Didn't Know Before 7 PHP Functions I Regret I Didn't Know Before Nov 13, 2024 am 09:42 AM

If you are an experienced PHP developer, you might have the feeling that you’ve been there and done that already.You have developed a significant number of applications, debugged millions of lines of code, and tweaked a bunch of scripts to achieve op

How To Set Up Visual Studio Code (VS Code) for PHP Development How To Set Up Visual Studio Code (VS Code) for PHP Development Dec 20, 2024 am 11:31 AM

Visual Studio Code, also known as VS Code, is a free source code editor — or integrated development environment (IDE) — available for all major operating systems. With a large collection of extensions for many programming languages, VS Code can be c

Explain JSON Web Tokens (JWT) and their use case in PHP APIs. Explain JSON Web Tokens (JWT) and their use case in PHP APIs. Apr 05, 2025 am 12:04 AM

JWT is an open standard based on JSON, used to securely transmit information between parties, mainly for identity authentication and information exchange. 1. JWT consists of three parts: Header, Payload and Signature. 2. The working principle of JWT includes three steps: generating JWT, verifying JWT and parsing Payload. 3. When using JWT for authentication in PHP, JWT can be generated and verified, and user role and permission information can be included in advanced usage. 4. Common errors include signature verification failure, token expiration, and payload oversized. Debugging skills include using debugging tools and logging. 5. Performance optimization and best practices include using appropriate signature algorithms, setting validity periods reasonably,

How do you parse and process HTML/XML in PHP? How do you parse and process HTML/XML in PHP? Feb 07, 2025 am 11:57 AM

This tutorial demonstrates how to efficiently process XML documents using PHP. XML (eXtensible Markup Language) is a versatile text-based markup language designed for both human readability and machine parsing. It's commonly used for data storage an

PHP Program to Count Vowels in a String PHP Program to Count Vowels in a String Feb 07, 2025 pm 12:12 PM

A string is a sequence of characters, including letters, numbers, and symbols. This tutorial will learn how to calculate the number of vowels in a given string in PHP using different methods. The vowels in English are a, e, i, o, u, and they can be uppercase or lowercase. What is a vowel? Vowels are alphabetic characters that represent a specific pronunciation. There are five vowels in English, including uppercase and lowercase: a, e, i, o, u Example 1 Input: String = "Tutorialspoint" Output: 6 explain The vowels in the string "Tutorialspoint" are u, o, i, a, o, i. There are 6 yuan in total

Explain late static binding in PHP (static::). Explain late static binding in PHP (static::). Apr 03, 2025 am 12:04 AM

Static binding (static::) implements late static binding (LSB) in PHP, allowing calling classes to be referenced in static contexts rather than defining classes. 1) The parsing process is performed at runtime, 2) Look up the call class in the inheritance relationship, 3) It may bring performance overhead.

What are PHP magic methods (__construct, __destruct, __call, __get, __set, etc.) and provide use cases? What are PHP magic methods (__construct, __destruct, __call, __get, __set, etc.) and provide use cases? Apr 03, 2025 am 12:03 AM

What are the magic methods of PHP? PHP's magic methods include: 1.\_\_construct, used to initialize objects; 2.\_\_destruct, used to clean up resources; 3.\_\_call, handle non-existent method calls; 4.\_\_get, implement dynamic attribute access; 5.\_\_set, implement dynamic attribute settings. These methods are automatically called in certain situations, improving code flexibility and efficiency.

See all articles