zoukankan      html  css  js  c++  java
  • 装饰模式(Decorator Pattern)

    • 装饰模式概述

    定义:动态地给一个对象增加一些附属的职责。

    装饰装饰,自然的理解就是在原有物品的基础上,增加一些别的东西,让它变得更令人满意。且装饰模式是在不改变对象本身的基础上就行额外的增加,更加灵活

    比如买房,首先买的是个空房,随后我们会放进去家具,和各种生活中要用的东西,让这个家变得更有家的味道,这就是装饰。我们也没有改变房子的结构。下次,也可以重新对家具进行布局,变成另外的风格

    • 装饰模式的结构和实现

    Component(抽象构件): (空房):具体构件和抽象装饰类的父类,声明了具体构件中的业务方法

    1 abstract class Component
    2 {
    3     public abstract void Operation();
    4 }

    ConcreteComponent(具体构件类):(刚买的北京二环内的一套房)抽象构件类的子类,用于定义具体的构件对象,实现在抽象构件中声明的方法。装饰类可以为它增加额外职责

    1 class ConcreteComponent : Component
    2 {
    3     public override void Operation()
    4     {
    5         //功能实现
    6     }

    Decorator(抽象装饰类):(家具城)抽象构件类的子类,用来给具体构件增加职责

     1 class Decorator :Component
     2 {
     3     private Component component;//抽象构件对象的引用
     4     
     5     public Decorator(Component component)
     6     {
     7         this.component = component;
     8     }
     9     
    10     public override void Operation()
    11     {
    12         component.Operation();//调用原有业务方法
    13     }
    14 }

    ConcreteDecorator(具体装饰类):(桌子 椅子 电器 床.......)抽象装饰类的子类,负责向构件增加新的职责

     1 class ConcreteDecorator :Decorator
     2 {
     3     public ConcreteDecorator(Component component ):base (component)
     4     {
     5     }
     6     
     7     public void AddedBehavir()
     8     {
     9         //新的业务方法
    10     }
    11     
    12     public override void Operation()
    13     {
    14         base.Operation();//调用原有方法
    15         AddedBehavir();//调用新的方法
    16     }
    17 }
    • 装饰模式的应用

     现有一家咖啡店,可以根据客户需求提供对应的咖啡。咖啡{  {浓缩咖啡(Espresso),25},{混合咖啡(House Blend),30},{重烘焙咖啡(Dark Roast),20}  }

    配料{ {摩卡(Mocha),10} ,{奶泡(Whip),8 },{牛奶 (Milk),6} }

    输出 浓缩咖啡,摩卡,牛奶  41

    分析:这就是个混合搭配的情况,只要你有钱,一种咖啡想搭配多少种配料都可以,那我们算算,3种咖啡,3种配料,一共可以搭配出多少种不同的饮料呢???不难算出,一种咖啡可以有8种(2^3)搭配,那么3种咖啡共有24种。那么这题写出24种类不就行了。当然是可以的。用继承,也是可以的。但是,由于自由搭配的情况,导致把全部情况写出来是完全低效的。所以,饮料类可以作为抽象类,配料类作为装饰类,使用装饰模式。我们想想,咖啡和配料的搭配,无论是咖啡搭配配料,还是配料搭配咖啡,效果都是一样的。但是,为了不影响咖啡类本身,我们是将配料类关联咖啡类的,即将咖啡类的对象作为自己的成员变量。

    Component(抽象构件):Coffee

    1 abstract  class Coffee//饮料类
    2 {    
    3          public abstract  double Cost();
    4          public abstract string Description();
    5 }
    View Code

    ConcreteComponent(具体构件类):浓缩咖啡(Espresso)、混合咖啡(House Blend)、重烘焙咖啡(Dark Roast)

     1 class Espresso : Coffee //特浓咖啡(Espresso) vs 滴漏咖啡(Drip)  特浓咖啡的制作原理是让热水在高压下流过一把压得严严实实的细腻的咖啡粉,咖啡因浓度较高,有咖啡脂。
     2     {
     3         public override double Cost()
     4         {
     5             return 25;
     6         }
     7 
     8         public override string Description()
     9         {
    10             return "浓缩咖啡";
    11         }
    12     }
    13 class DarkRoast : Coffee //深培咖啡:按照美式分级,咖啡豆的烘焙由浅至深可分为八个阶段。咖啡的味道主要取决于烘焙度,一般烘焙程度越深苦味越浓,烘焙程度越低,酸味就越高。
    14     {
    15         public override double Cost()
    16         {
    17             return 20;
    18         }
    19 
    20         public override string Description()
    21         {
    22             return "深培咖啡";
    23         }
    24     }
    25  class HouseBlend : Coffee //北美特别流行的黑咖啡,它属于混合咖啡,配方因地而有所不同,但主要成分都有50%以上的哥伦比亚咖啡豆.可以翻译为家常咖啡。
    26     {    
    27         public override double Cost()
    28         {
    29             return 30;
    30         }
    31         public override string Description()
    32         {
    33             return "混合咖啡";
    34         }
    35     }
    View Code

    Decorator(抽象装饰类):Ingredients

     1 abstract class Ingredients:Coffee 
     2     {
     3         private Coffee coffee;
     4 
     5         public Ingredients(Coffee beverage)
     6         {
     7             this.coffee = beverage;
     8         }
     9         public override double Cost()
    10         {
    11             return coffee.Cost();
    12         }
    13         public override string Description()
    14         {
    15             return coffee.Description();
    16         }  
    17     }
    View Code

    ConcreteDecorator(具体装饰类):Mocha、Whip、Milk

     1 class Mocha:Ingredients  
     2     {
     3         public Mocha(Coffee beverage):base(beverage )
     4         {
     5         }
     6   
     7         public override double Cost()
     8         {
     9             return base.Cost() + 10;
    10         }
    11 
    12         public override string Description()
    13         {
    14             return base.Description()+",摩卡";
    15         }
    16     }
    17 
    18     class Whip : Ingredients //奶泡,由全脂牛奶搅拌而成,可拉丝
    19     {
    20         public Whip(Coffee beverage)
    21             : base(beverage)
    22         {   
    23         }
    24 
    25         public override double Cost()
    26         {
    27             return base.Cost() + 8;
    28         }
    29 
    30         public override string Description()
    31         {
    32             return base.Description()+",奶泡";
    33         }
    34     }
    35 
    36     class Milk : Ingredients //牛奶
    37     {
    38         public Milk(Coffee beverage)
    39             : base(beverage)
    40         {
    41         }
    42 
    43         public override double Cost()
    44         {
    45             return base.Cost() + 6;
    46         }
    47 
    48         public override string Description()
    49         {
    50             return base.Description() + ",牛奶";
    51         }
    52     }
    View Code

    Progream:

     1 class Program
     2     {
     3         static void Main(string[] args)
     4         {
     5             Coffee b = new Espresso();
     6 
     7             Coffee b1 = new Mocha(b);
     8 
     9             Coffee b2 = new Whip(b1);
    10 
    11             Coffee b3 = new Milk(b2);
    12 
    13             Console.WriteLine("名称:{0}
    价格:{1}",b3.Description (),b3.Cost ());
    14 
    15             Console.Read();
    16         }
    17     }
    View Code 

    以上就是装饰模式的介绍,装饰模式的优点是它的扩展比使用继承更灵活,不会使类很多很多。接下来是对关于Coffee的东西,感兴趣的可以看下

  • 相关阅读:
    使用lambda的精简写法
    lambda实现集合遍历 排序
    stream流 list转map
    stream.min
    lambda实现线程调用
    stream.allMatch
    stream.reduce
    stream流 of
    Stream流 list转set
    SQL Server 游标的简单介绍 转载
  • 原文地址:https://www.cnblogs.com/ygsworld/p/10848828.html
Copyright © 2011-2022 走看看