Maison  >  Article  >  développement back-end  >  Modèle de conception PHP (créatif)

Modèle de conception PHP (créatif)

藏色散人
藏色散人avant
2019-09-04 13:18:122679parcourir

Avant-propos

Avec l'augmentation de l'expérience dans les projets de programmation, du service de la logique métier à la conception globale du projet. Reconnaître l'importance des modèles de conception dans le processus de développement et suivre les cinq principes de référence de S.O.L.I.D. Cela a élargi mes horizons, rendu le code plus flexible et plus beau. La beauté est la philosophie de la construction de toutes choses

Les modèles de conception que nous apprenons sont divisés en trois catégories : le modèle de créateur, le modèle structurel et les modèles comportementaux. ; les modèles créationnels sont liés à la création d'objets ; les modèles structurels traitent de la combinaison de classes ou d'objets ; et les modèles comportementaux décrivent la manière dont les classes ou les objets interagissent et comment attribuer les responsabilités ;

Contenu : Cet article présente ; la création de modèles de conception PHP. Y compris : le mode Singleton, le mode Multiton, le mode Méthode d'usine, le mode Usine abstraite, le mode Usine simple, le mode Prototype, le mode Pool d'objets (Pool), le mode Builder (Builder)

Recommandé : "Tutoriel PHP"

(1) Mode Singleton (Singleton)

● La définition

garantit qu'une classe n'a qu'une seule instance et fournit un accès global pointez-le. Il n'y a qu'un seul objet de cette classe dans la mémoire système, ce qui permet d'économiser les ressources système. Pour certains objets qui doivent être fréquemment créés et détruits, l'utilisation du mode singleton peut améliorer les performances du système.

Quantity Exemple de code

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) Mode multi-instances (Multiton)

● Définition

en mode multi-instance , une classe multi-instance peut avoir plusieurs instances, et la classe multi-instance doit créer et gérer ses propres instances, et fournir ses propres instances au monde extérieur. 1. Enregistrez le conteneur via un conteneur d'instance. 2. Utiliser la construction privée pour empêcher la construction externe. 3. Fournissez la méthode getInstantce() pour obtenir des instances.

● Exemple de code Deux objets sont instanciés plusieurs fois via une classe

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) Modèle de méthode Factory (méthode Factory)

Quantity Définition

reporte l'instanciation de la classe (la création de produits spécifiques) à la sous-classe de la classe d'usine (usine spécifique), c'est-à-dire que la sous-classe décide quelle instance devrait être Quelle classe

● Exemple de code : Xiaocheng possède une usine de transformation du plastique (produit uniquement des produits de classe A) ; à mesure que les besoins du client changent, le client doit produire des produits de classe B ); Il est très difficile de modifier la configuration et les modifications de l'usine de transformation du plastique d'origine. En supposant que les besoins du client changent la prochaine fois, un nouveau changement augmentera considérablement le coût ; Xiaocheng a décidé d'acheter une usine de branche de plastique B pour produire des produits de classe B.

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) Modèle d'usine abstraite (Abstract Factory)

● Définition

Créez une série d'objets liés ou dépendants. Habituellement, des classes sont créées qui implémentent la même interface. Le client de l'usine abstraite ne se soucie pas de la manière dont les objets sont créés, il sait simplement comment ils fonctionnent ensemble.

● Exemple de code : il y a deux usines, l'usine A est responsable du transport et l'usine B produit des produits numériques

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) Mode usine simple (usine simple) <.>

Quantity Définition

Le modèle d'usine simple est une version simplifiée du modèle d'usine. Rôle d'usine - produit concret - produit abstrait

● Exemple de code :

Une ferme veut vendre des fruits au marché. Il existe trois sortes de fruits à la ferme, les pommes et les raisins. Nous imaginons : 1. Les fruits ont de multiples attributs, chaque attribut est différent, mais ils ont quelque chose en commun : pousser, planter, récolter et manger. De nouveaux fruits pourraient être ajoutés à l'avenir, et nous devons définir une interface pour standardiser les méthodes qu'ils doivent mettre en œuvre

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 &#39;apple&#39;:
                return new apple();
                break;
            case &#39;grape&#39;:
                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 = &#39;&#39; , $errType = 1){
        $this->msg = $msg;
        $this->errType = $errType;
    }  
}
/**
 * 获取水果实例化的方法
 */
try{
    $appleInstance = farmer::factory(&#39;apple&#39;);
    var_dump($appleInstance);
}catch(badFruitException $err){
    echo $err->msg . "_______" . $err->errType;
}

(6) Prototype (Prototype)

. ● Définir

est plus rentable que de créer un objet normalement (new Foo () ) en créant d'abord un prototype puis en le clonant.

● Exemple de code : Définir le titre de chaque livre

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 = &#39;Bar&#39;;
    public function __clone()
    {
    }
}
class FooBookPrototype extends BookPrototype
{
    /**
    * @var string
    */
    protected $category = &#39;Foo&#39;;
    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) Mode Pool d'objets (Pool)

● Définition

Le pool d'objets peut être utilisé pour construire et stocker une série d'objets et les récupérer en cas de besoin. Dans les situations où le coût d'initialisation des instances est élevé, le taux d'instanciation est élevé et les instances disponibles sont insuffisantes, les pools d'objets peuvent améliorer considérablement les performances. Dans les situations où le temps requis pour créer des objets (en particulier sur le réseau) est incertain, les objets requis peuvent être obtenus dans un court laps de temps via un pool d'objets.

● Exemple de code

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) Modèle de générateur (Builder)

● Définition

Convertir un objet complexe La construction est séparé de sa représentation, permettant au même processus de construction de créer différentes représentations

● 2) Exemple de code Construire des camions et des voitures du même standard. Semblable à Transformers, les mêmes pièces peuvent être combinées de différentes manières

● Divisées en Directeur, responsable de la construction, BuilderInterface pour créer des interfaces, normaliser les normes de construction, TruckBuilder pour créer des classes de camions, CarBuilder pour créer des classes de voitures <.>

Classe publique de pièces de véhicules, classe de pièces de portes de roue de moteur de voiture de camion, classe de test DirectorTest

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

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!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer