En gilet, vous êtes génial: une analyse du motif décorateur

Cet article est le troisième article de la série Design Pattern. Aujourd'hui, j'étudierai principalement le motif décorateur.

Je ne sais pas si vous n’avez pas un tel sentiment. Lorsque vous lisez et étudiez, vous pouvez le comprendre, mais vous l’oubliez après un certain temps. Plusieurs questions, afin de consolider les connaissances acquises, enchaînent ces points de connaissances dans votre cerveau. J'espère pouvoir continuer à penser à plusieurs reprises, mettre les points en lignes et enfin former un bloc de connaissances, le digérer.

Étude avec des questions

  1. Quel est le mode décorateur?
  2. Dans quels scénarios avez-vous besoin d'utiliser le mode décorateur?
  3. Comment mettre en œuvre le motif décorateur?
  4. Quels cas peuvent être reflétés dans le cadre commun ou le code source?

Le concept de motif décorateur

Jetons d'abord un coup d'œil à la description du mode décorateur:

Le "mode décorateur" associe dynamiquement des responsabilités aux objets. Pour étendre la fonctionnalité, les décorateurs offrent une alternative plus flexible que l'héritage.

«Nouveaux principes de conception» : les classes doivent être ouvertes pour extension et fermées pour modification.

Bien que la définition ci-dessus explique le «rôle» du motif décorateur, elle n'explique pas comment «l'appliquer» réellement dans notre implémentation.

Ensuite, nous étudierons son diagramme de classes et l'analyserons soigneusement en combinaison avec le diagramme de classes:

À partir du diagramme de classes ci-dessus, comprenons le modèle de décorateur

  • Le décorateur et l'objet décoré ont le même supertype
  • Vous pouvez envelopper un objet (le composant spécifique d'un composant) avec un ou plusieurs décorateurs
  • Puisque le décorateur et l'objet décoré ont le même supertype, l'objet décoré peut être utilisé à la place de l'objet original (emballé) en toute occasion
  • «Le décorateur peut ajouter son propre comportement avant ou après le comportement du décorateur confié pour atteindre un but précis.» Nous le verrons clairement plus loin dans la façon de l'utiliser.
  • Les objets peuvent être décorés à tout moment, vous pouvez donc décorer de manière dynamique et illimitée des objets avec vos décorateurs préférés au moment de l'exécution

scènes à utiliser

Il existe maintenant un café qui peut vendre plusieurs types de café différents, tels que le moka, le cappuccino, le macchiato, le campana, etc. Et chaque café spécifique peut également être ajouté avec différentes saveurs, telles que la mousse de lait, le caramel, le lait de soja, le moka, etc. Différentes saveurs sont nécessaires pour avoir des prix finaux différents.Si cette scène est conçue en utilisant des idées OO, que feriez-vous?

Il ne fait aucun doute que cette scène convient très bien au mode décorateur.Tout d'abord, le décorateur est notre variété de café, et le décorateur est nos différentes épices, de sorte que lors du calcul du prix, nous pouvons commander couche par couche pour obtenir le résultat final, pas grand chose à dire Voyez si nous utilisons un motif décorateur pour décorer notre café.

En regardant l'exemple de café Starbucks que nous avons donné ci-dessus, correspond-il au cadre du diagramme de classes du modèle de décorateur? Tout le monde peut y réfléchir attentivement.

Consolider et développer

Utilisons maintenant votre modèle de décoration ci-dessus pour créer une scène. Vérifions s'il peut être mis en œuvre sans modifier le code existant et découvrez le charme du modèle de conception.

"Commandez un double latte de mousse de lait de soja moka?"

Est-ce très pratique? Utilisons le mode décorateur pour élargir la combinaison et découvrir le charme. .

la mise en oeuvre

Combinons l'exemple ci-dessus et jetons un coup d'œil à l'implémentation du code:

// 饮料的基础类,即component
public abstract class Beverage {
    String description = "Unknown Beverage";

    public String getDescription() {
 return description;  }  // cost必须在子类实现  public abstract double cost(); } 

La classe abstraite d'assaisonnement, à savoir la classe décoratrice:

// 调料抽象类即装饰者类,这个类必须要能替换 Beverage,所以要继承自 Beverage 类
public abstract class CondimentDecorator extends Beverage {

    public abstract String getDescription();
}

Maintenant que nous avons la classe de base, voici une boisson spécifique:

// 蓝山
public class BlueMountainCoffee extends Beverage {
    public BlueMountainCoffee() {
        description = "BlueMountainCoffee";
    }
 @Override  public double cost() {  return 0;  } }  // 卡布奇诺 public class Cappuccino extends Beverage {  public Cappuccino() {  description = "Cappuccino";  }  @Override  public double cost() {  return 23;  } }  // 意式浓缩咖啡 public class Espresso extends Beverage {  public Espresso() {  description = "Espresso";  }  @Override  public double cost() {  return 25;  } } // 拿铁 public class Latte extends Beverage {  public Latte() {  description = "Latte";  }  @Override  public double cost() {  return .89;  } } 

Maintenant qu'il existe des composants concrets et des composants abstraits, nous pouvons implémenter des décorateurs concrets en comparant le diagramme de classe de modèle de décorateur:

// 摩卡是一个装饰者,所以扩展自 CondimentDecorator
public class Mocha extends CondimentDecorator {
    Beverage beverage;
    public Mocha(Beverage beverage) {
        this.beverage = beverage;
 }  @Override  public String getDescription() {  return beverage.getDescription() + ",Mocha";  }   // 首先调用委托被装饰者对象,以计算价钱,然后再加上Mocha价钱  @Override  public double cost() {  return .20 + beverage.cost();  } } // 豆浆 public class Soy extends CondimentDecorator {  Beverage beverage;  public Soy(Beverage beverage) {  this.beverage = beverage;  }  @Override  public String getDescription() {  return beverage.getDescription() + ",Soy";  }  @Override  public double cost() {  return 2.0 + beverage.cost();  } } 

La prochaine étape consiste à montrer le charme du mode décorateur:

// 测试类
public class StarbuzzCoffee {
    public static void main(String[] args) {
        // 一杯Espresso,不加调料
        Beverage beverage = new Espresso();
 System.out.println(beverage.getDescription() + "$" + beverage.cost());  // 一杯加摩卡和豆浆的蓝山咖啡  Beverage beverage1 = new BlueMountainCoffee();  beverage1 = new Mocha(beverage1);  beverage1 = new Soy(beverage1);  System.out.println(beverage1.getDescription() + "$" + beverage1.cost());  } } 

À l'heure actuelle, les objets que nous créons sont tous nouveaux codés en dur, ce qui n'est pas très convivial.Au fur et à mesure que nous apprenons le mode usine dans le suivi, tout ira bien, continuez à apprendre.

Décorateur en réalité

Voici quelques exemples de modèles de décorateurs dans jdk qui sont généralement utilisés

E / S Java

L'ordre indiqué provient du décorateur -> décorer

LineNumberInputStream -> BufferedInputStream -> FileInputStream

En un coup d'œil, c'est fondamentalement le même que le diagramme de classe de modèle de décorateur que nous avons mentionné ci-dessus. Je crois que lorsque vous relirez les classes dans le package d'E / S Jvaa, vous allez sûrement lancer une exclamation "wow".


Le texte intégral est terminé! combat

Ce n’est pas facile d’être original. J’espère que vous pourrez me rendre un petit service. Si vous pensez que le contenu de cet article est quelque chose que vous avez gagné, aidez-moi à cliquer sur "Je regarde", ou à le transférer et à le partager pour que plus d’amis le voient.

Je suppose que tu aimes

Origine blog.csdn.net/taurus_7c/article/details/106969515
conseillé
Classement