Heim  >  Artikel  >  Backend-Entwicklung  >  Fallanalyse von PHP-Prototypmustern

Fallanalyse von PHP-Prototypmustern

php中世界最好的语言
php中世界最好的语言Original
2018-05-17 11:42:152195Durchsuche

Dieses Mal werde ich Ihnen eine Fallanalyse des PHP-Prototypmodus vorstellen. Was sind die Vorsichtsmaßnahmen bei der Verwendung des PHP-Prototypmodus?

Das Prototyp-Entwurfsmuster ist interessant, weil es eine Klontechnik verwendet, um instanziierte Objekte zu kopieren. Dabei handelt es sich bei den Instanzen um Batch-Instanzen. Der Zweck des Prototyp-Entwurfsmusters besteht darin, die zu reduzieren Aufwand für die Instanziierung von Objekten durch die Verwendung von Klonen. Anstatt neue Objekte aus einer Klasse zu instanziieren, können Sie einen Klon einer vorhandenen Instanz verwenden.

Klonfunktion

Der Schlüssel zur Verwendung des Prototyping-Musters in PHP besteht darin, zu verstehen, wie die integrierte Funktionclone() verwendet wird.

<?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();

zum Ausführen Das Ergebnis ist wie folgt

Aussehen: gutaussehend
chenqionghe
Aussehen: immer noch gutaussehend
chenqionghe

$cloneBoy-Instanz ist eine von $boy geklonte Instanz von Boy. Sie kann auf die zugreifen Dieselben Eigenschaften wie $boy und mutieren sie wie eine direkte Instanz der Boy-Klasse.

Hinweis: Bei einer geklonten Instanz ist das Schlüsselwort clone die Instanz. Die Klasse instanziiert eine andere Instanz ( Verwenden Sie das Schlüsselwort clone, um eine Kopie der Klasse zu erstellen. Die Methode clone des Objekts kann jedoch nicht direkt aufgerufen werden Beachten Sie, dass beim Klonen die Aktionen im clone Konstruktor

Einfaches Prototypbeispiel nicht gestartet werden Das Ziel der Forschung ist es, einen Prototyp einer Fruchtfliege zu bauen und dann, sobald eine Mutation auftritt, diese mutierte Fruchtfliege zu bauen.

Abstrakte Klassenschnittstelle und konkrete Implementierung Die beiden konkreten Klassenimplementierungen des Prototyps (IPrototype) repräsentieren jeweils Fruchtfliegen unterschiedlichen Geschlechts, einschließlich Geschlechtsvariablen und Verhaltensweisen unterschiedlicher Geschlechter.

IPrototype .php

<?php
abstract class IPrototype
{
  public $eyeColor;
  public $winBeat;
  public $unitEypes;
  abstract function clone();
}
Der Unterschied zwischen den beiden Implementierungen von IPrototype spiegelt sich im Geschlecht wider, das durch Konstanten identifiziert wird, eine ist MÄNNLICH und die andere ist FEMAIL Variable, männlich Nach der Paarung der Fruchtfliegen wird diese boolesche Variable auf „true“ gesetzt. Die weibliche Fruchtfliege verfügt über eine $fruchtbarkeitsvariable, die einen numerischen Wert enthält, der die Fortpflanzungsfähigkeit der männlichen Fruchtfliege angibt (Anzahl der gelegten Eier):

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(){}
}

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(){}
}

Kunde

Im Prototyping-Modus ist die Client-Klasse tatsächlich ein unverzichtbarer Bestandteil. Der Grund dafür ist, dass die konkrete Implementierung der Unterklasse zwar als Vorlage für die Instanz verwendet wird, die spezifische Arbeit des Klonens der Instanz unter Verwendung derselben Vorlage jedoch von der Client-Klasse ausgeführt wird

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();
Die Laufergebnisse sind wie folgt

Augenfarbe: rot
Flügelschläge/Sekunde: 220

Augeneinheiten: 760
Geschlecht: MÄNNLICH
Verpaart: echtAugenfarbe: rot
Flügelschläge/Sekunde: 220
Augeneinheiten: 760
Geschlecht: WEIBLICH
Anzahl der Eier : 186Augenfarbe: lila
Flügelschläge/Sekunde: 220
Augeneinheiten: 760
Geschlecht: FEMAIL
Anzahl der Eier: 92

Der Prototypmodus basiert auf dem Der Kunde ist der Teilnehmer, der den Klonvorgang durchführt. Da das Klonen ein Schlüsselelement beim Prototyping ist, ist der Kunde ein grundlegender Teilnehmer und nicht nur eine Anforderungsklasse.

Moderne Unternehmensorganisation

In Bezug auf kreative Designmuster eignen sich moderne Unternehmensorganisationen oft für die Implementierung von Prototypen Beim Programmieren müssen viele gemeinsame Merkmale modelliert werden.

Ein Software-Engineering-Unternehmen ist für die Entwicklung von Produkten verantwortlich Koordination der Ressourcen und die Marketingabteilung) ist für den Verkauf, die Werbung und das Gesamtmarketing des Produkts verantwortlich.

Einkapselung in der Schnittstelle

在这个原型实现中,首先为程序的接口(一个抽象类)增加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(&#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() {}
}

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() {}
}

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() {}
}

以上这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();

解释:

客户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类中获取方法和设置方法使用的代码提示指示一个接口,而不是一个抽象类的具体实现.所以, 只要增加的单元正确地实现了这个接口,就能顺利地增加到应用中, 而不会带来波动,也不需要对程序中的其他参与者进行重构.

Es können nicht nur konkretere Kurse hinzugefügt werden, sondern auch einzelne Kurse können problemlos geändert werden, ohne dass es zu Störungen kommt. Angenommen, die Marketingabteilung dieser Organisation entscheidet, dass sie zusätzlich zu ihren bestehenden Abteilungen ein spezifisches Online-Marketing benötigt Daher erfordert die Wechsel-/Falloperation einen neuen Zweig (Fall) und ein neues privates Attribut (Variable), um die neue Abteilung zu beschreiben, ohne dass sich dies auf andere Teilnehmer auswirkt Dies verursacht keinen Schaden. Je größer der Umfang der Anwendung, desto wichtiger ist dies. Es ist ersichtlich, dass das Prototyping-Entwurfsmuster nicht nur die Konsistenz unterstützt, sondern auch flexible Änderungen die PHP-Welt

Da PHP eine serverseitige Sprache und ein wichtiges Werkzeug für die Interaktion mit der MySQL-Datenbank

ist, sind Prototyping-Patterns hier besonders nützlich, anstatt separate Objekte zu erstellen Als erstes Element der Datenbank kann PHP das Prototype-Muster verwenden, um eine Instanz einer konkreten Klasse zu erstellen und dann die verbleibenden Instanzen (Datensätze) mithilfe der Daten in der Datenbank zu klonen.

Lernen Nach dem Klonvorgang verglichen Zum Prozess der direkten Instanziierung fragen Sie sich möglicherweise: „Was ist der Unterschied?“ Mit anderen Worten: Warum erfordert das Klonen weniger Ressourcen als das direkte Instanziieren des Objekts? Der Klon erhält nicht alle Eigenschaften der Originalklasse, auch die der übergeordneten Schnittstelle, und erbt außerdem alle vom Konstruktor generierten Werte Die in den Objekteigenschaften gespeicherten Werte werden Teil des geklonten Objekts. Daher gibt es keinen Rückgabekonstruktor. Wenn Sie feststellen, dass Ihr geklontes Objekt tatsächlich auf die vom Konstruktor generierten Werte zugreifen muss, weist dies darauf hin, dass dies der Fall ist Die Klasse muss umgestaltet werden, damit Instanzen über alle benötigten Informationen verfügen und diese Daten an geklonte Objekte übergeben können.

Im Allgemeinen eignet sich das Prototypmuster sehr gut für viele verschiedene Arten von PHP-Projekten Ein Problem erfordert sogar, dass der Prototypenmodus sowohl im Kreativmodus als auch im Prototypenmodus verwendet werden kann. Ich glaube, dass Sie die Methode beherrschen, nachdem Sie den Fall in diesem Artikel gelesen haben. Weitere spannende Informationen finden Sie in anderen verwandten Artikeln auf der chinesischen PHP-Website!

Empfohlene Lektüre:

Anwendungsfallanalyse des PHP-Closure-Prinzips (OCP)

Detaillierte Erläuterung des PHP-Abhängigkeitsinversionsfalls

Das obige ist der detaillierte Inhalt vonFallanalyse von PHP-Prototypmustern. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn