zoukankan      html  css  js  c++  java
  • 设计模式——装饰者模式

    咖啡店里咖啡中可以加不同的配料–摩卡、牛奶、糖、奶泡;不同的饮品加上不同的配料有不同的价钱,怎样实现呢?

    可能你的第一印象会想到使用继承, 
    1. 首先定义一个咖啡基类 
    2. 对于加糖的,加牛奶的,加摩卡的 ,加奶泡的,分别写一个子类继承 
    3. 对于加糖,又加奶的写一个类,对于对于加糖,又摩卡的写一个类,对于对于加糖、又奶泡的写一个类,对于加糖,又加奶、摩卡的写一个类—- 
    说到这里,你会发现这里四种配料就要写十几种实现类了,那如果我们的配料是二十几种或者三十几种呢,那么使用继承这种 方式肯定会使我们的子类爆炸,那要怎样解决你,答案就是使用装饰者模式

    装饰者模式是在已有功能的基础之上,动态地添加更多 功能的一种方式,这些新加的代码装饰了原有类的 核心职责或主要行为。

    Component:定义一个对象接口,可以给这些对象动态的添加职责。

    ConcreteComponent:定义一个对象,可以给这些对象添加一些职责。

    Decorator:维持一个指向Component的指针并定义一个与Component接口一致的接口。

    ConcreteDecorator:继承自Decorator,向组件添加职责。

    咖啡抽象类

     1  abstract class Coffee
     2     {
     3         /**
     4         *
     5         * @return 返回价格
     6         */
     7         public abstract int getPrice();
     8 
     9         /**
    10          * 返回名字
    11          * @return
    12          */
    13         public abstract String getName();
    14     }

    调料抽象类

    1 abstract class Decorator:Coffee
    2     {
    3         public abstract String getDescription();  
    4     }

    生产一杯原味咖啡

     1  class CoffeeA:Coffee
     2     {
     3         public override int getPrice()
     4         {
     5             return 1;
     6         }
     7 
     8         public override string getName()
     9         {
    10             return "CoffeeA";
    11         }
    12     }

    生产牛奶配料

     1  class MilkDecorator:Decorator
     2     {
     3         Coffee mCoffee;
     4         /**
     5      * 通过组合的方式把Coffee对象传递进来
     6      *
     7      * @param coffee
     8      */
     9     public MilkDecorator(Coffee coffee) {
    10         this.mCoffee = coffee;
    11     }
    12 
    13     public override int getPrice() {
    14         return mCoffee.getPrice()+10;
    15     }
    16 
    17     public override String getName()
    18     {
    19         return mCoffee.getName() + "addMilk";
    20     }
    21     }

    生产抹茶配料

     1  class MochaDecorator:Decorator
     2     {
     3      Coffee mCoffee;
     4         /**
     5      * 通过组合的方式把Coffee对象传递进来
     6      *
     7      * @param coffee
     8      */
     9      public MochaDecorator(Coffee coffee)
    10     {
    11         this.mCoffee = coffee;
    12     }
    13 
    14      public override int getPrice()
    15      {
    16         return mCoffee.getPrice()+30;
    17     }
    18 
    19      public override String getName()
    20      {
    21         return  mCoffee.getName() +"addMocha";
    22     }
    23     }

    由于具体的配料类继承与配料抽象类,而配料抽象类又继承与咖啡类,因此配料类实现时需要实现这两个类中中的所有方法。

    接下来我们开始对咖啡装饰

     1 Coffee A = new CoffeeA();
     2 Console.WriteLine("品牌:" + A.getName() + " 价格:" + A.getPrice());
     3 
     4 A = new SoyDecorator(A );
     5 Console.WriteLine("品牌:" + A .getName());
     6 
     7 B = new MochaDecorator(B);
     8 Console.WriteLine("品牌:" + A .getName());
     9 
    10  
    11 
    12 Console.ReadLine();

    装饰者模式中用到了继承,但是这里装饰者模式用继承是为了保证装饰者和被装饰者有共同的超类,而不是为了给被装饰的类扩展新的特性,而装饰者模式中新的特性是通过类与类的组合(has-a的关系)而得到的,所以把装饰者模式和继承看做同一类设计思想是不恰当的。

     自我感觉和组合模式太相似。

    学习于    https://www.cnblogs.com/coffeeSS/p/5405787.html

  • 相关阅读:
    Windsor
    .net 常见异常及其翻译
    nginx
    数据库访问层封装
    web api HttpConfiguration
    ENode, 领域模型,DDD
    缓存 Redis
    win7 快捷键
    visual studio 快捷键
    c# 正则表达式
  • 原文地址:https://www.cnblogs.com/cwmizlp/p/9059871.html
Copyright © 2011-2022 走看看