zoukankan      html  css  js  c++  java
  • 设计模式学习 之 装饰模式

    装饰者模式(Decorator):定义:在不必改变原类文件和使用继承的情况下,动态的扩展一个对象的功能。

    首相了解什么时候会用到 装饰者模式?

     当我们在给一个类或对象 增加额外的 功能时, 通常想到的是 直接改变 类,添加功能,这显然违背了 开闭原则,是不可取的,可能会影响到其他正常功能的使用。

     还有一种 就是使用继承。 继承 不但 可以 得到 父类的 方法 ,而且 还可以构建自己 需要的方法。 但这种 方法是静态的特质(所谓静态特质,就是说如果想要某种功能,我们必须在编译的时候就要定义这个类,这也是强类型语言的特点。静态,就是指在编译的时候要确定的东西;动态,是指运行时确定的东西),扩展方式十分不灵活,同时,随着需求改变的增多,继承的层次也 越来越多,各种类 造成了 类的膨胀。这时可以使用 同样的 另一种方式:对象组合

    使用场合

    1. 在不影响其他对象的情况下,以动态的,透明的方式给单个对象添加职责;
    2. 处理那些可以撤销的职责;
    3. 当不能采用生成子类的方法进行扩充时。一种情况是,可能存在大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。

    在装饰模式中的各个角色有:
      (1)抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。
      (2)具体构件(Concrete Component)角色:定义一个将要接收附加责任的类。
      (3)装饰(Decorator)角色:持有一个构件(Component)对象的实例,并实现一个与抽象构件接口一致的接口。
      (4)具体装饰(Concrete Decorator)角色:负责给构件对象添加上附加

    下面通过一个小例子来说明一下, 饭店宴席 是 吸引顾客 的特色之一 , 但是 一桌 美味的 宴席 不能是  不变的 , 为了 吸引 大量的 顾客 需要 动态的 去 调整  宴席 的

    组合方式, 以 一桌 宴席 包括 鸡,鸭,鱼,鹅,肉,青菜 为准

        /// <summary>
        /// Component 是一个对象接口,可以动态的给这些对象添加职责
        /// Component 是被装饰对象的基类
        /// </summary>
    
        public abstract class Component
        {
            public abstract void AddFood();
    
    
        }
    View Code
    /// <summary>
        /// 定义 准备接受职责 的类
        /// Concretecomponent 是具体被装饰的对象
        /// </summary>
       public   class Concretecomponent :Component
        {
    
           public override void AddFood()
           {     
           
           }
    
          
        }
    View Code
    /// <summary>
        /// 装饰抽象类 继承 Component ,从外部 扩展 Component 的功能
        /// Decorator  是装饰者抽象类
        /// </summary>
        public abstract class Decorator : Component
        {
    
            protected Component Component;
    
    
    
            /// <summary>
            /// 设置Component 利用 Setcomponent 来对 对对象进行包装,这样每个装饰对象的实现 就和如何 使用这个对象 分离开了
            /// 每个装饰对象只关心自己的 功能  不需要关心如何被添加到对象之中(我只关心自己的菜,不关心要怎么上)
            /// 
            /// </summary>
            /// <param name="Component"></param>
            /// Setcomponent 布置餐桌 
    
            public void Setcomponent(Component Component)
            {
                this.Component = Component;
              
            
            }
    
            public override void AddFood()
            {
    
                if (Component != null)
                {
                    //重写 Operation ,实际执行的 是 Component 的 Operation 
                    Component.AddFood();
                
                }
    
    
            }
    
    
    
    
    
        }
    View Code
        /// <summary>
        ///  ConcreteDecoratoe 是 具体装饰类
        /// </summary>
       public class ConcreteDecoratoeChicen:Decorator
        {
           public override void AddFood()
           {
               /// 首先先执行原Component AddFood 的方法,然后再 执行本类中 AddFood 的方法
               base.AddFood();
               AddChicenfood();
           }
           /// <summary>
           /// 本类独有的方法,设置自己想要 的流程
           /// </summary>
           private void AddChicenfood() 
           {   
               Console.WriteLine("上一道美味的小鸡炖蘑菇");    
           }
        }
    
       public class ConcreteDecoratoeDuck : Decorator
       {
           public override void AddFood()
           {
               /// 首先先执行原Component AddFood 的方法,然后再 执行本类中 AddFood 的方法
               base.AddFood();
               AddDuckfood();
           }
           /// <summary>
           /// 本类独有的方法,设置自己想要 的流程
           /// </summary>
           private void AddDuckfood()
           {
               Console.WriteLine("来一道北京烤鸭");
           }
       }
    
       public class ConcreteDecoratoeFish : Decorator
       {
           public override void AddFood()
           {
               /// 首先先执行原Component AddFood 的方法,然后再 执行本类中 AddFood 的方法
               base.AddFood();
               AddFishfood();
           }
           /// <summary>
           /// 本类独有的方法,设置自己想要 的流程
           /// </summary>
           private void AddFishfood()
           {
               Console.WriteLine("上一道美味的深海大鲟鱼");
           }
       }
    
    
       public class ConcreteDecoratoeGoosey : Decorator
       {
           public override void AddFood()
           {
               /// 首先先执行原Component AddFood 的方法,然后再 执行本类中 AddFood 的方法
               base.AddFood();
               AddGooseyfood();
           }
           /// <summary>
           /// 本类独有的方法,设置自己想要 的流程
           /// </summary>
           private void AddGooseyfood()
           {
               Console.WriteLine("上一道酱香鹅");
           }
       }
    
    
       public class ConcreteDecoratoeMeat : Decorator
       {
           public override void AddFood()
           {
               /// 首先先执行原Component AddFood 的方法,然后再 执行本类中 AddFood 的方法
               base.AddFood();
               AddMeatfood();
           }
           /// <summary>
           /// 本类独有的方法,设置自己想要 的流程
           /// </summary>
           private void AddMeatfood()
           {
               Console.WriteLine("上一道红烧肉");
           }
       }
    
    
       public class ConcreteDecoratoeVegetable : Decorator
       {
           public override void AddFood()
           {
               /// 首先先执行原Component AddFood 的方法,然后再 执行本类中 AddFood 的方法
               base.AddFood();
               AddVegetablefood();
           }
           /// <summary>
           /// 本类独有的方法,设置自己想要 的流程
           /// </summary>
           private void AddVegetablefood()
           {
               Console.WriteLine("上一道小青菜");
           }
       }
    View Code
    调用:
    Concretecomponent FoodTable = new Concretecomponent();
    
               ConcreteDecoratoeChicen chicen = new ConcreteDecoratoeChicen();
               ConcreteDecoratoeGoosey goosey = new ConcreteDecoratoeGoosey();
               ConcreteDecoratoeMeat meat = new ConcreteDecoratoeMeat();
               ConcreteDecoratoeVegetable vegetable = new ConcreteDecoratoeVegetable();
                ConcreteDecoratoeFish fish = new ConcreteDecoratoeFish();
                ConcreteDecoratoeDuck duck = new ConcreteDecoratoeDuck();
    
    
                Console.WriteLine("开始上菜:
    ");
            
                vegetable.Setcomponent(FoodTable);
    
                Console.WriteLine("
    ");
    
                goosey.Setcomponent(vegetable);
                Console.WriteLine("
    ");
    
                chicen.Setcomponent(goosey);
                Console.WriteLine("
    ");
    
                fish.Setcomponent(chicen);
                Console.WriteLine("
    ");
    
                duck.Setcomponent(fish);
    
                Console.WriteLine("
    ");
                meat.Setcomponent(duck);
    
                Console.WriteLine("
    ");
    
                meat.AddFood();
               
               
               
               Console.Read();
    View Code

    优点

    1. Decorator模式与继承关系的目的都是要扩展对象的功能,但是Decorator可以提供比继承更多的灵活性。
    2. 通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。

    缺点

    1. 这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性。
    2. 装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。
    3. 装饰模式是针对抽象组件(Component)类型编程。但是,如果你要针对具体组件编程时,就应该重新思考你的应用架构,以及装饰者是否合适。当然也可以改变Component接口,增加新的公开的行为,实现“半透明”的装饰者模式。在实际项目中要做出最佳选择。

    个人感觉装饰者 模式 更像 大树 主干 和 分支的关系 。 

  • 相关阅读:
    Select查询执行顺序
    javascript异步处理
    ASP.NET MVC WebAPI请求
    函数声明和函数表达式
    var声明的成员变量和函数内声明的变量区别
    网页大小自适应方案
    MVC Html.AntiForgeryToken() 防止CSRF攻击
    Jquery跨域请求
    螺旋模型
    快速原型模型
  • 原文地址:https://www.cnblogs.com/lfyy/p/5111678.html
Copyright © 2011-2022 走看看