Maison  >  Article  >  développement back-end  >  Qu'est-ce que le motif décorateur et en quoi est-il différent du motif pont ?

Qu'est-ce que le motif décorateur et en quoi est-il différent du motif pont ?

齐天大圣
齐天大圣original
2020-08-05 08:57:482830parcourir

L'histoire du ramen

Les nouilles ramen sont vendues dans les restaurants ramen. Le ramen est divisé en petits bols et grands bols. et un grand bol coûte 6 yuans 9 yuans. De plus, si vous ajoutez du bœuf, vous devez ajouter 6 yuans, un œuf équivaut à 1 yuan, un gros steak équivaut à 5 yuans et un morceau de riz croustillant équivaut à 1 yuan. Si vous utilisez la méthode d'écriture traditionnelle pour définir des nouilles ramen avec des prix différents, vous devez écrire 8 catégories (nombre de portions de ramen * nombre de plats d'accompagnement). Si le magasin de nouilles introduit désormais une nouvelle taille de portion – bol moyen, alors 4 nouvelles catégories doivent être ajoutées. Cela posera un problème : une explosion de classe.

Si vous avez lu mon article précédent https://www.php.cn/php-weizijiaocheng-457250.html, après avoir compris le mode pont, vous sentirez que ce problème peut être résolu Mode pont à résoudre. Divisez-le en deux grandes catégories, les nouilles et les plats d'accompagnement.

Ci-dessous, nous utilisons le mode pont pour résoudre le problème ci-dessus. Le code est le suivant :

interface INoodle
{
    function cost ();
    function desc ();
}

class BigNoodle implements INoodle
{
    private $cost = 9.0;
    private $dish = null;
    
    public function __construct(IDish $dish)
    {
        $this->dish = $dish;
    }
    
    public function cost()
    {
        return $this->cost + $this->dish->cost();
    }
    
    public function desc()
    {
        return $this->dish->desc() . '大碗拉面';
    }
}

class SmallNoodle implements INoodle
{
    private $cost = 6.0;
    private $dish = null;
    
    public function __construct(IDish $dish)
    {
        $this->dish = $dish;
    }
    
    public function cost()
    {
        return $this->cost + $this->dish->cost();
    }
    
    public function desc()
    {
        return $this->dish->desc() . '小碗拉面';
    }
}

interface IDish
{
    function cost ();
    function desc ();
}

class Beef implements IDish
{
    public function cost ()
    {
        return 6;
    }
    
    public function desc()
    {
        return '牛肉';
    }
}

class Crust implements IDish
{
    public function cost ()
    {
        return 1;
    }
    
    public function desc()
    {
        return '锅巴';
    }
}

class Egg implements IDish
{
    public function cost ()
    {
        return 1;
    }
    
    public function desc()
    {
        return '鸡蛋';
    }
}

Mode décorateur

. Utiliser le mode pont Cela résout le problème de quasi-explosion, mais vous savez aussi que lorsque nous allons manger des nouilles, parfois nous n'avons pas besoin de plats d'accompagnement, juste des nouilles, ou nous avons besoin de plusieurs plats d'accompagnement. Par exemple, je veux un grand. bol de ramen au bœuf et ajoutez 3 morceaux de nouilles de riz croustillantes et 2 œufs. Pour cette exigence, le mode pont ne peut pas être utilisé. Pour résoudre ce problème, nous pouvons utiliser un autre modèle de conception structurelle : le modèle décorateur.

Le modèle de décoration est un modèle de conception structurelle qui vous permet de lier de nouveaux comportements à l'objet d'origine en plaçant l'objet dans un objet d'encapsulation spécial qui contient le comportement.

Pour comprendre le motif du décorateur, vous pouvez imaginer une poupée - poupées gigognes

Quest-ce que le motif décorateur et en quoi est-il différent du motif pont ?

Chaque ensemble de poupées équivaut à ajouter une poupée Objet de décoration . Au moment de l'exécution, l'objet décoratif le plus à l'extérieur (prendre le calque externe) sera exécuté, puis exécuté couche par couche. Vous ne comprenez peut-être pas ce que cela signifie maintenant, mais peut-être comprendrez-vous si vous relisez cette phrase après avoir lu le contenu suivant.

J'ai dessiné moi-même un diagramme de classes UML, c'est un peu moche, s'il vous plaît, cliquez dessus

Quest-ce que le motif décorateur et en quoi est-il différent du motif pont ?

Implémentation du code

abstract class Noodles
{
    abstract function cost ();
    abstract function desc ();
}

class BigNoodle extends Noodles
{
    private $cost = 9.0;
    
    public function cost()
    {
        return $this->cost;
    }
    
    public function desc()
    {
        return '大碗拉面';
    }
}

class SmallNoodle extends Noodles
{
    private $cost = 6.0;
    
    public function cost()
    {
        return $this->cost;
    }
    
    public function desc()
    {
        return  '小碗拉面';
    }
}

abstract class NoodlesDecorator extends Noodles
{
}

class Beef extends NoodlesDecorator
{
    private $desc = '牛肉';
    private $cost = 6.0;
    protected $noodles = null;
    
    public function __construct(Noodles $noodels)
    {
        $this->noodles = $noodels;
    }
    
    public function cost ()
    {
        return $this->cost + $this->noodles->cost();
    }
    
    public function desc ()
    {
        return $this->desc . $this->noodles->desc();
    }
}

// egg、curst类代码省略,除了属性值不一样基本和Beef一致

Le code du test est le suivant

$noodles = new BigNoodle();
$beefBigNoodles = new Beef($noodles);
$eggBeffBigNoodles = new Egg($beefBigNoodles);

echo $eggBeffBigNoodles->desc();
echo $eggBeffBigNoodles->cost() . '元';

Résumé : Un grand bol de ramen aux œufs et au bœuf 16 yuans

Résumé

Réfléchissez à une question, pourquoi la quantité de ramen n'est-elle pas utilisée comme objet de décoration ici ? Pensez-y, commanderiez-vous un grand bol et un petit bol de ramen ?

Caractéristiques du motif de décorateur

  • Le décorateur et l'objet décoré ont le même supertype

  • Un objet peut être enveloppé avec un ou plusieurs décorateurs

  • L'objet peut être décoré à tout moment, vous pouvez donc utiliser vos décorateurs préférés de manière dynamique et illimitée au moment de l'exécution pour décorer des objets.

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:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn