Heim  >  Artikel  >  Backend-Entwicklung  >  PHP-Entwurfsmuster (kreativ)

PHP-Entwurfsmuster (kreativ)

藏色散人
藏色散人nach vorne
2019-09-04 13:18:122613Durchsuche

Vorwort

Mit zunehmender Erfahrung in Programmierprojekten, von der Bereitstellung der Geschäftslogik bis zum Gesamtdesign für das Projekt. Erkennen Sie die Bedeutung von Designmustern im Entwicklungsprozess und befolgen Sie die fünf Benchmark-Prinzipien von S.O.L.I.D. Es hat meinen Horizont erweitert, den Code flexibler gemacht und schöner ausgesehen.

Die Designmuster, die wir lernen, sind in drei Kategorien unterteilt: Erstellermuster, Strukturmuster, Verhaltensmuster ; Erstellungsmuster beziehen sich auf die Kombination von Klassen oder Objekten; Verhaltensmuster beschreiben, wie Klassen oder Objekte interagieren und wie Verantwortlichkeiten zugewiesen werden die Erstellung von PHP-Designmustern. Einschließlich: Singleton-Modus, Multiton-Modus, Factory-Methodenmodus, Abstract Factory-Modus, Simple Factory-Modus, Prototype-Modus, Objektpoolmodus (Pool), Builder-Modus (Builder)

Empfohlen: "

PHP-Tutorial

"

(1) Singleton-Modus (Singleton)

● Definition

stellt sicher, dass eine Klasse nur eine Instanz hat und bietet einen globalen Zugriff darauf hinweisen. Es gibt nur ein Objekt dieser Klasse im Systemspeicher, wodurch Systemressourcen gespart werden. Bei einigen Objekten, die häufig erstellt und zerstört werden müssen, kann die Verwendung des Singleton-Modus die Systemleistung verbessern.

● Codebeispiel

class Singleton
{
    /**
    * @var Singleton
    */
    private static $instance;
    /**
    * 不允许从外部调用以防止创建多个实例
    * 要使用单例,必须通过 Singleton::getInstance() 方法获取实例
    */
    private function __construct()
    {
    }
    /**
    * 通过懒加载获得实例(在第一次使用的时候创建)
    */
    public static function getInstance(): Singleton
    {
        if (null === static::$instance) {
            static::$instance = new static();
        }
        return static::$instance;
    }
    /**
    * 防止实例被克隆(这会创建实例的副本)
    */
    private function __clone()
    {
    }
    /**
    * 防止反序列化(这将创建它的副本)
    */
    private function __wakeup()
    {
    }
}

(2) Mehrfachinstanzmodus (Multiton)

● Definition

im Mehrinstanzmodus , eine Multi-Instanz-Klasse kann mehrere Instanzen haben, und die Multi-Instanz-Klasse muss ihre eigenen Instanzen erstellen und verwalten und ihre eigenen Instanzen der Außenwelt zur Verfügung stellen. 1. Speichern Sie den Container über einen Instanzcontainer. 2. Nutzen Sie privates Bauen, um externen Bau zu verhindern. 3. Stellen Sie die Methode getInstantce() bereit, um Instanzen zu erhalten

● Codebeispiel Zwei Objekte werden mehrfach über eine Klasse instanziiert

abstract class Multiton { 
    private static $instances = array(); 
    public static function getInstance() { 
        $key = get_called_class() . serialize(func_get_args());
        if (!isset(self::$instances[$key])) { 
            $rc = new ReflectionClass(get_called_class());
            self::$instances[$key] = $rc->newInstanceArgs(func_get_args());
        }
        return self::$instances[$key]; 
    }
    /**
     * 该私有对象阻止实例被克隆
     */
    private function __clone()
    {
    }
    /**
     * 该私有方法阻止实例被序列化
     */
    private function __wakeup()
    {
    }
} 
class Hello extends Multiton { 
    public function __construct($string = 'World') { 
        echo "Hello $string\n"; 
    } 
} 
class GoodBye extends Multiton { 
    public function __construct($string = 'my', $string2 = 'darling') { 
        echo "Goodbye $string $string2\n"; 
    }
}
$a = Hello::getInstance('World'); 
$b = Hello::getInstance('bob'); 
// $a !== $b 
$c = Hello::getInstance('World'); 
// $a === $c 
$d = GoodBye::getInstance(); 
$e = GoodBye::getInstance();
// $d === $e 
$f = GoodBye::getInstance('your'); 
// $d !== $f

(3) Factory-Methodenmuster (Factory-Methode)

● Definition

verschiebt die Instanziierung der Klasse (die Erstellung spezifischer Produkte) auf die Unterklasse der Fabrikklasse (spezifische Fabrik), d. h. die Unterklasse entscheidet, welche Instanz Welche Klasse sollte sein

● Codebeispiel: Xiaocheng verfügt über eine Kunststoffverarbeitungsfabrik (produziert nur Produkte der Klasse A); wenn sich die Bedürfnisse der Kunden ändern, muss der Kunde Produkte der Klasse B herstellen. Es ist sehr schwierig, die Konfiguration und Änderungen der ursprünglichen Kunststoffverarbeitungsanlage zu ändern. Unter der Annahme, dass der Kunde beim nächsten Mal Änderungen vornehmen muss, wird eine erneute Änderung die Kosten erheblich erhöhen.

abstract class Product{
    public abstract function Show();
}
//具体产品A类
class  ProductA extends  Product{
    public function Show() {
        echo "生产出了产品A";
    }
}
//具体产品B类
class  ProductB extends  Product{
    public function Show() {
        echo "生产出了产品B";
    }
}
abstract class Factory{
    public abstract function Manufacture();
}
//工厂A类 - 生产A类产品
class  FactoryA extends Factory{
    public function Manufacture() {
        return new ProductA();
    }
}
//工厂B类 - 生产B类产品
class  FactoryB extends Factory{
    public function Manufacture() {
        return new ProductB();
    }
}

(4) Abstract Factory-Muster (Abstract Factory)

● Definition

Erstellen Sie eine Reihe verwandter oder abhängiger Objekte. Normalerweise werden Klassen erstellt, die dieselbe Schnittstelle implementieren. Dem Kunden der abstrakten Fabrik ist es egal, wie die Objekte erstellt werden, er weiß nur, wie sie zusammen funktionieren.

● Codebeispiel: Es gibt zwei Fabriken, Fabrik A ist für den Transport verantwortlich und Fabrik B produziert digitale Produkte

interface Product
{
    public function calculatePrice(): int;
}
class ShippableProduct implements Product
{
    /**
     * @var float
     */
    private $productPrice;
    /**
     * @var float
     */
    private $shippingCosts;
    public function __construct(int $productPrice, int $shippingCosts)
    {
        $this->productPrice = $productPrice;
        $this->shippingCosts = $shippingCosts;
    }
    public function calculatePrice(): int
    {
        return $this->productPrice + $this->shippingCosts;
    }
}
class DigitalProduct implements Product
{
    /**
     * @var int
     */
    private $price;
    public function __construct(int $price)
    {
        $this->price = $price;
    }
    public function calculatePrice(): int
    {
        return $this->price;
    }
}
class ProductFactory
{
    const SHIPPING_COSTS = 50;
    public function createShippableProduct(int $price): Product
    {
        return new ShippableProduct($price, self::SHIPPING_COSTS);
    }
    public function createDigitalProduct(int $price): Product
    {
        return new DigitalProduct($price);
    }
}

(5) Einfacher Fabrikmodus (Einfache Fabrik)

● Definition

Das einfache Fabrikmuster ist eine optimierte Version des Fabrikmusters. Fabrikrolle – konkretes Produkt – abstraktes Produkt

● Codebeispiel:

Ein Bauernhof möchte Früchte auf dem Markt verkaufen. Auf dem Bauernhof gibt es drei Arten von Früchten: Äpfel und Weintrauben. Wir stellen uns vor: 1. Früchte haben mehrere Eigenschaften, jede Eigenschaft ist anders, aber sie wachsen, pflanzen, ernten und essen etwas. In Zukunft könnten neue Früchte hinzugefügt werden, und wir müssen eine Schnittstelle definieren, um die Methoden zu standardisieren, die sie implementieren müssen

interface fruit{
    /**
     * 生长
     */
    public function grow();
    /**
     * 种植
     */
    public function plant();
    /**
     * 收获
     */
    public function harvest();
    /**
     * 吃
     */
    public function eat();
}
class apple implements fruit{
    //苹果树有年龄
    private $treeAge;
    //苹果有颜色
    private $color;
    public function grow(){
        echo "grape grow";
    }
    public function plant(){
        echo "grape plant";
    }
    public function harvest(){
        echo "grape harvest";
    }
    public function eat(){
        echo "grape eat";
    }
    //取苹果树的年龄
    public function getTreeAge(){
        return $this->treeAge;
    }
    //设置苹果树的年龄
    public function setTreeAge($age){
        $this->treeAge = $age;
        return true;
    }
}
class grape implements fruit{
    //葡萄是否有籽
    private $seedLess;
    public function grow(){
        echo "apple grow";
    }
    public function plant(){
        echo "apple plant";
    }
    public function harvest(){
        echo "apple harvest";
    }
    public function eat(){
        echo "apple eat";
    }
    //有无籽取值
    public function getSeedLess(){
        return $this->seedLess;
    }
    //设置有籽无籽
    public function setSeedLess($seed){
        $this->seedLess = $seed;
        return true;
    }
}
class farmer
{
    //定义个静态工厂方法
    public static function factory($fruitName){
        switch ($fruitName) {
            case 'apple':
                return new apple();
                break;
            case 'grape':
                return new grape();
                break;
            default:
                throw new badFruitException("Error no the fruit", 1);
                break;
        }
    }
}
class badFruitException extends Exception
{
    public $msg;
    public $errType;
    public function __construct($msg = '' , $errType = 1){
        $this->msg = $msg;
        $this->errType = $errType;
    }  
}
/**
 * 获取水果实例化的方法
 */
try{
    $appleInstance = farmer::factory('apple');
    var_dump($appleInstance);
}catch(badFruitException $err){
    echo $err->msg . "_______" . $err->errType;
}

(6) Prototyp (Prototyp)

● Das Definieren von

ist kostengünstiger als das normale Erstellen eines Objekts (new Foo () ), indem zunächst ein Prototyp erstellt und dieser dann geklont wird.

● Codebeispiel: Legen Sie den Titel für jedes Buch fest

abstract class BookPrototype
{
    /**
    * @var string
    */
    protected $title = 0;
    /**
    * @var string
    */
    protected $category;
    abstract public function __clone();
    public function getTitle(): string
    {
        return $this->title;
    }
    public function setTitle($title)
    {
       $this->title = $title;
    }
}
class BarBookPrototype extends BookPrototype
{
    /**
    * @var string
    */
    protected $category = 'Bar';
    public function __clone()
    {
    }
}
class FooBookPrototype extends BookPrototype
{
    /**
    * @var string
    */
    protected $category = 'Foo';
    public function __clone()
    {
    }
}
$fooPrototype = new FooBookPrototype();
$barPrototype = new BarBookPrototype();
for ($i = 5; $i < 10; $i++) {
    $book = clone $fooPrototype;
    $book->setTitle(&#39;Foo Book No &#39; . $i);
    var_dump(new FooBookPrototype == $book);
}
for ($i = 0; $i < 5; $i++) {
    $book = clone $barPrototype;
    $book->setTitle(&#39;Bar Book No &#39; . $i);
    var_dump(new BarBookPrototype == $book);
}

(7) Objektpoolmodus (Pool)

● Definition

Der Objektpool kann verwendet werden, um eine Reihe von Objekten zu erstellen, zu speichern und bei Bedarf abzurufen. In Situationen, in denen die Kosten für die Initialisierung von Instanzen hoch sind, die Instanziierungsrate hoch ist und die verfügbaren Instanzen nicht ausreichen, können Objektpools die Leistung erheblich verbessern. In Situationen, in denen die zum Erstellen von Objekten erforderliche Zeit (insbesondere über das Netzwerk) ungewiss ist, können die erforderlichen Objekte in kurzer Zeit über einen Objektpool abgerufen werden.

● Codebeispiel

class Factory {
    protected static $products = array();
    public static function pushProduct(Product $product) {
        self::$products[$product->getId()] = $product;
    }
    public static function getProduct($id) {
        return isset(self::$products[$id]) ? self::$products[$id] : null;
    }
    public static function removeProduct($id) {
        if (array_key_exists($id, self::$products)) {
            unset(self::$products[$id]);
        }
    }
}
Factory::pushProduct(new Product(&#39;first&#39;));
Factory::pushProduct(new Product(&#39;second&#39;));
print_r(Factory::getProduct(&#39;first&#39;)->getId());
// first
print_r(Factory::getProduct(&#39;second&#39;)->getId());
// second

(8) Builder-Muster (Builder)

● Definition

Konvertieren eines komplexen Objekts Der Build ist von seiner Darstellung getrennt, sodass mit demselben Build-Prozess unterschiedliche Darstellungen erstellt werden können

● 2) Codebeispiel Erstellen Sie Lastkraftwagen und Autos desselben Standards. Ähnlich wie bei Transformers können die gleichen Teile auf unterschiedliche Weise kombiniert werden

● Unterteilt in Director, verantwortlich für die Konstruktion, BuilderInterface zum Erstellen von Schnittstellen, Standardisieren von Konstruktionsstandards, TruckBuilder zum Erstellen von LKW-Klassen, CarBuilder zum Erstellen von Pkw-Klassen

Klasse für öffentliche Fahrzeugteile, Klasse für LKW-Automotor-Radtürteile, DirectorTest-Testklasse

class Director
{
    public function build(BuilderInterface $builder): Vehicle
    {
        $builder->createVehicle();
        $builder->addDoors();
        $builder->addEngine();
        $builder->addWheel();
        return $builder->getVehicle();
    }
}
interface BuilderInterface
{
    public function createVehicle();
    public function addWheel();
    public function addEngine();
    public function addDoors();
    public function getVehicle(): Vehicle;
}
class TruckBuilder implements BuilderInterface
{
    /**
    * @var Truck
    */
    private $truck;
    public function addDoors()
    {
        $this->truck->setPart(&#39;rightDoor&#39;, new Door());
        $this->truck->setPart(&#39;leftDoor&#39;, new Door());
    }
    public function addEngine()
    {
        $this->truck->setPart(&#39;truckEngine&#39;, new Engine());
    }
    public function addWheel()
    {
        $this->truck->setPart(&#39;wheel1&#39;, new Wheel());
        $this->truck->setPart(&#39;wheel2&#39;, new Wheel());
        $this->truck->setPart(&#39;wheel3&#39;, new Wheel());
        $this->truck->setPart(&#39;wheel4&#39;, new Wheel());
        $this->truck->setPart(&#39;wheel5&#39;, new Wheel());
        $this->truck->setPart(&#39;wheel6&#39;, new Wheel());
    }
    public function createVehicle()
    {
        $this->truck = new Truck();
    }
    public function getVehicle(): Vehicle
    {
        return $this->truck;
    }
}
class CarBuilder implements BuilderInterface
{
    /**
    * @var Car
    */
    private $car;
    public function addDoors()
    {
        $this->car->setPart(&#39;rightDoor&#39;, new Door());
        $this->car->setPart(&#39;leftDoor&#39;, new Door());
        $this->car->setPart(&#39;trunkLid&#39;, new Door());
    }
    public function addEngine()
    {
        $this->car->setPart(&#39;engine&#39;, new Engine());
    }
    public function addWheel()
    {
        $this->car->setPart(&#39;wheelLF&#39;, new Wheel());
        $this->car->setPart(&#39;wheelRF&#39;, new Wheel());
        $this->car->setPart(&#39;wheelLR&#39;, new Wheel());
        $this->car->setPart(&#39;wheelRR&#39;, new Wheel());
    }
    public function createVehicle()
    {
        $this->car = new Car();
    }
    public function getVehicle(): Vehicle
    {
        return $this->car;
    }
}
abstract class Vehicle
{
    /**
    * @var object[]
    */
    private $data = [];
    /**
    * @param string $key
    * @param object $value
    */
    public function setPart($key, $value)
    {
        $this->data[$key] = $value;
    }
}
class Truck extends Vehicle
{
}
class Car extends Vehicle
{
}
class Engine extends Vehicle
{
}
class Wheel extends Vehicle
{
}
class Door extends Vehicle
{
}
class DirectorTest
{
    public function testCanBuildTruck()
    {
        $truckBuilder = new TruckBuilder();
        return (new Director())->build($truckBuilder);
    }
    public function testCanBuildCar()
    {
        $carBuilder = new CarBuilder();
        return (new Director())->build($carBuilder);
    }
}
$directorTest = new DirectorTest();
var_dump($directorTest->testCanBuildTruck());
var_dump($directorTest->testCanBuildCar());

Das obige ist der detaillierte Inhalt vonPHP-Entwurfsmuster (kreativ). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:learnku.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen