Cette fois, je vais vous apporter une analyse de cas du mode prototype PHP. Quelles sont les précautions lors de l'utilisation du mode prototype PHP. Ce qui suit est un cas pratique, jetons un coup d'œil.
Le Prototype Design Pattern est intéressant car il utilise une technique de clonage pour copier des objets instanciés. Les nouveaux objets sont créés en copiant des instances prototypes. Ici, les instances sont des instances batch. Le but du prototype design pattern est de réduire le nombre d'instances. surcharge de l'instanciation d'objets à l'aide de clones. Au lieu d'instancier de nouveaux objets à partir d'une classe, vous pouvez utiliser un clone d'une instance existante.
Fonction de clonage
La clé pour utiliser le modèle de prototypage en PHP est de comprendre comment utiliser les fonctions intégréesclone()
.
<?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 'look : '.$this->face;; echo '<br />'.$this->name.'<br />'; } public function clone() {} } $boy = new Boy(); $boy->display(); $cloneBoy = clone $boy; $cloneBoy->face = "still handsome"; $cloneBoy->display();
Les résultats d'exécution sont les suivants
look : beau
chenqionghe
look : toujours beau
chenqionghe
L'instance $cloneBoy est une instance de Boy$ boy cloné, qui peut accéder au mêmes propriétés que $boy, et mute-les comme une instance directe de la classe Boy
Remarque : Pour les instances clonées, le mot-clé clone sera La classe de cette instance instancie une autre instance (. l'utilisation du mot-clé clone peut créer une copie de la classe. Si possible, la méthode clone
de l'objet sera automatiquement appelée, mais la méthode clone
de l'objet ne peut pas être appelée directement. Concernant le processus, il y a une chose à noter. que le clonage ne lancera pas les actions dans le constructeur
Exemple de prototype simple
Prenons l'étude des fruits. mouches à titre d'exemple. Le but de la recherche est de construire un prototype de mouche des fruits, puis une fois qu'une mutation se produit, de construire cette mouche des fruits mutante
Interface de classe abstraite et implémentation concrète
Les deux implémentations concrètes de classe du prototype (IPrototype) représentent respectivement des mouches des fruits de genres différents, y compris des variables de genre et des comportements de genres différents.
IPrototype.php
<?php abstract class IPrototype { public $eyeColor; public $winBeat; public $unitEypes; abstract function clone(); }
La différence entre les deux implémentations d'IPrototype se reflète dans le sexe. Le sexe est identifié par des constantes, l'une est MALE et l'autre est FEMAIL. Les mouches des fruits mâles ont une variable booléenne $accouplement. Une fois que la mouche des fruits mâle s'est accouplée, cette variable booléenne sera définie sur true. La mouche des fruits femelle a une variable $fecondity, qui contient une valeur numérique, indiquant la capacité de reproduction de la mouche des fruits mâle (nombre d'œufs pondus) :
MaleProto.php
<?php include_once('IPrototype.php'); class MaleProto extends IPrototype { const gender = "MALE"; public $mated; public function construct() { $this->eyeColor = "red"; $this->winBeat = "220"; $this->unitEypes = "760"; } public function clone(){} }
FemaleProto.php
<?php include_once('IPrototype.php'); class FemaleProto extends IPrototype { const gender = "FEMAIL"; public $fecundity; public function construct() { $this->eyeColor = "red"; $this->winBeat = "220"; $this->unitEypes = "760"; } public function clone(){} }
Client
Dans le modèle de conception de prototypage, la classe Client est en effet un élément indispensable.La raison en est que bien que l'implémentation concrète de la sous-classe soit utilisée comme modèle d'instance, le travail spécifique de clonage de l'instance à l'aide du même modèle est complété par la classe Client
Client.php
<?php function autoload($class_name) { include_once $class_name.'.php'; } 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 = '186'; $this->updatedCloneFly->eyeColor = "purple"; $this->updatedCloneFly->winBeat = "220"; $this->updatedCloneFly->unitEyes = '750'; $this->updatedCloneFly->fecundity = '92'; //通过类型提示方法发送 $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();
Les résultats d'exécution sont les suivants
Couleur des yeux : rouge
Battements d'ailes/seconde : 220
Unités oculaires : 760
Sexe : MÂLE
Accouplement : vraiCouleur des yeux : rouge
Battements d'ailes/seconde : 220
Unités oculaires : 760
Sexe : FEMAIL
Nombre d'œufs : 186Couleur des yeux : violet
Battements d'ailes/seconde : 220
Unités oculaires : 760
Sexe : FEMAIL
Nombre d'œufs : 92
Le mode prototype repose sur l'approbation du client. Le processus de clonage utilise un prototype spécifique. Dans ce processus de conception, le client est le participant qui réalise le clonage. Le clonage étant un élément clé de la conception du prototype, le client est un participant fondamental. pas seulement une classe de requêtes.
Organisations d'entreprise modernes
En termes de modèles de conception créatifs, les organisations d'entreprise modernes sont très adaptées à la mise en œuvre de prototypes. De nos jours, les organisations d'entreprise ont souvent. des structures hiérarchiques complexes et énormes, comme la programmation orientée objet, pour modéliser de nombreuses caractéristiques communes. Décrivez maintenant une entreprise de génie logiciel à travers un exemple
Une entreprise de génie logiciel est une organisation moderne typique dont le département d'ingénierie est responsable. créant les produits, et le service de gestion Gérant la coordination et l'organisation des ressources, le service marketing est responsable de la vente, de la promotion et de la commercialisation globale des produits
Encapsulation dans l'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(); }
利用这些获取方法和设置方法, 所有属性的值都通过继承的保护变量来设置.采用这种设计, 扩展类及其实例可以得到更好的封装.
接口实现
3个IAcmePrototype子类都必须实现"dept"抽象方法以及clone()
方法.类似地, 每个具体原型类还包含一个常量UNIT,它提供一个赋值,可以由实例(包括克隆的对象)作为标识
首先来看市场部的Marketing类:
Marketing.php
<?php include_once('IAcmePrototype.php'); 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() {} }
setDept()
方法的实现使用了一个参数.并不是直接输入市场部的部门,这个方法的参数是一个数字码, 通过一个switch语句,限制了3种可接受的情况和默认情况,别外两个原型实现也类似
Management.php
<?php include_once('IAcmePrototype.php'); 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() {} }
Engineering.php
<?php include_once('IAcmePrototype.php'); 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() {} }
以上这3个具体原型实现分别有其特定用途,不过它们都符合接口,可以创建各个原型实现的一个实例, 然后根据需要克隆多个实例.这个克隆的工作由Client类完成
客户
客户的设置非常简单: 分别创建各个具体原型的一个实例, 然后按以下列表来克隆各个实例:
市场部门实例:
-----市场部门克隆
-----市场部门克隆
管理部门实例
-----管理部门克隆
工程部门实例
-----工程部门克隆
-----工程部门克隆
将来只使用这些克隆对象.使用获取方法和设置方法将各个特定情况的信息赋给这些克隆对象.以下是Client的实现
Client.php
<?php function autoload($class_name) { include_once $class_name.'.php'; } class Client { private $market; private $manage; private $engineer; public function construct() { $this->makeConProto(); $Tess = clone $this->market; $this->setEmployee($Tess, "Tess Smith" , 101, 'ts101-1234', 'tess.png'); $this->showEmployee($Tess); $Jacob = clone $this->market; $this->setEmployee($Jacob, "Jacob Jones" , 101, 'jj101-2234', 'jacob.png'); $this->showEmployee($Jacob); $Ricky = clone $this->manage; $this->setEmployee($Ricky, "Ricky Rodriguez" , 203, 'rr101-5634', 'ricky.png'); $this->showEmployee($Ricky); $Olivaia = clone $this->engineer; $this->setEmployee($Olivaia, "Olivaia Perez" , 302, 'op301-1278', 'olivia.png'); $this->showEmployee($Olivaia); $John = clone $this->engineer; $this->setEmployee($John, "John Jacson" , 101, 'jj301-14548', 'john.png'); $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='150' height='150' /><br />"; echo $employeeNow->getName().'<br />'; echo $employeeNow->getDept().':'.$employeeNow::UNIT.'<br />'; echo $employeeNow->getId().'<hr />'; } private function setEmployee(IAcmePrototype $employeeNow, $nm, $dp, $id, $px) { $employeeNow->setName($nm); $employeeNow->setDept($dp); $employeeNow->setId($id); $employeeNow->setPic($px); } } $worker = new Client();
解释:
客户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类中获取方法和设置方法使用的代码提示指示一个接口,而不是一个抽象类的具体实现.所以, 只要增加的单元正确地实现了这个接口,就能顺利地增加到应用中, 而不会带来波动,也不需要对程序中的其他参与者进行重构.
Non seulement des cours plus concrets peuvent être ajoutés, mais les cours individuels peuvent être facilement modifiés sans provoquer de perturbations. Par exemple, supposons que le service marketing de cette organisation décide qu'en plus de ses services existants, il a besoin d'un marketing en ligne spécifique. En conséquence, l'opération switch/case nécessite une nouvelle branche (case) et un nouvel attribut privé (variable) pour décrire le nouveau département. Ce changement sera gelé dans une classe distincte, sans affecter les autres participants depuis ce changement. ne causera pas de dommages, plus l'échelle de l'application est grande, plus cela est important. On peut voir que le modèle de conception de prototypage prend non seulement en charge la cohérence, mais prend également en charge les changements flexibles dans
. le monde PHP
Étant donné que PHP est un langage côté serveur et un outil important pour interagir avec la base de données MySQL, les modèles de prototypage sont ici particulièrement utiles au lieu de créer des objets séparés pour. le premier élément de la base de données, PHP peut utiliser le modèle Prototype pour créer une instance d'une classe concrète, puis cloner les instances restantes (enregistrements) en utilisant les données de la base de données
Apprendre après le processus de clonage, comparé. au processus d'instanciation directe, vous pouvez demander : « Quelle est la différence ? » En d'autres termes, pourquoi le clonage nécessite-t-il moins de ressources que l'instanciation directe de l'objet ? La différence n'est pas directement visible lorsqu'un objet est instancié via le clonage. ne démarre pas un constructeur. Le clone récupère toutes les propriétés de la classe d'origine, même celles de l'interface parent, et hérite également de toutes les valeurs transmises à l'objet instancié. Toutes les valeurs générées par le constructeur et les valeurs . stocké dans les propriétés de l'objet fera partie de l'objet cloné. Par conséquent, il n'y a pas de constructeur de retour. Si vous constatez que votre objet cloné a vraiment besoin d'accéder aux valeurs générées par le constructeur mais ne peut pas y accéder, cela indique que le la classe doit être refactorisée pour que les instances puissent disposer de toutes les informations dont elles ont besoin et transmettre ces données aux objets clonés.
En général, le modèle de prototype est très adapté à de nombreux types de projets PHP s'il est résolu. un problème nécessite même que le mode Prototype puisse être utilisé à la fois en mode création et créatif
Je pense que vous maîtrisez la méthode après avoir lu le cas dans cet article. Pour des informations plus intéressantes, veuillez prêter attention aux autres articles connexes sur. le site PHP chinois !
Lecture recommandée :
Analyse du cas d'utilisation du principe de fermeture PHP (OCP)
Explication détaillée du cas d'inversion de dépendance PHP
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!