• 03、装饰模式(Decorator)


    一、概念:

      动态的给一个对象添加一些额外的职责,就增加的功能来说,装饰模式比生成子类更为灵活。【DP】

    二、通俗的理解:

      装饰模式是利用其中的方法为来对对象进行包装的,这样每个包装对象的事项就和如何使用这个对象分离了,

    每个对象只关心自己的功能,不需要关心如何添加到对象链中去。

    三、模式类图

                                   

     

    四、对类图的解释;

    Component是定义一个对象接口,可以给这些对象动态的添加职责,ConcreateComponent是定义了一个具体的对象,

    也可以给这个对象添加 一些职责。Decorator,装饰抽象类,继承了Componet,从外类来扩展Component类的功能,

    但对于Component来说,是无需知道Descorator的存在的。至于ConcreteDescorator就是具体的装饰对象,起到给Component添加职责的功能。

    五、类图代码

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace Decorator
     8 {
     9     //Component类;
    10 
    11     public abstract class Component
    12     {
    13         public abstract void Operation();           //定义的接口中的实现方法
    14     }
    15 
    16     public class ConcreteComponent : Component
    17     {
    18         public override void Operation()
    19         {
    20             Console.WriteLine("具体对象的实现操作");
    21         }
    22     }
    23 
    24     public class Decorator : Component
    25     {
    26         protected Component component;
    27 
    28         public void SetComponent(Component component)
    29         {
    30             //设置Component
    31             this.component = component;
    32         }
    33 
    34         public override void Operation()
    35         //重写Operation(),实际是执行的是Component的Operation()
    36         {
    37             if (component != null)
    38             {
    39                 component.Operation();
    40             }
    41         }
    42     }
    43 
    44     public class ConcreteDecoratorA : Decorator
    45     {
    46         public override void Operation()
    47         {
    48             base.Operation();       //关键的一步
    49             SubedBehavior();
    50             Console.WriteLine("具体装饰对象A的操作");
    51         }
    52         public void SubedBehavior()
    53         {
    54             //用来区别ConcreateDecoratorA和 ConcreateDecoratorB的区别
    55         }
    56     }
    57 
    58 
    59     public class ConcreteDecoratorB : Decorator
    60     {
    61 
    62         public override void Operation()
    63         {
    64             base.Operation();
    65             AddedBehavior();
    66             Console.WriteLine("具体装饰对象B的操作");
    67         }
    68         public void AddedBehavior()
    69         {
    70             //用来区别ConcreateDecoratorA和 ConcreateDecoratorB的区别
    71         }
    72     }
    73 
    74     //客户端代码的实现;
    75     class Program
    76     {
    77         static void Main(string[] args)
    78         {
    79             ConcreteComponent c = new ConcreteComponent();
    80             ConcreteDecoratorA d1 = new ConcreteDecoratorA();
    81             ConcreteDecoratorB d2 = new ConcreteDecoratorB();
    82 
    83             d1.SetComponent(c);
    84             d2.SetComponent(d1);
    85             d2.Operation();
    86             //装饰的方法是:首先用ConcreteComponent实例话对象c,然后用ConcreteDecorateA的实例化对象d1来包装c,在用ConcreteDecoratorB的对象d2来包装d1,最终执行d2的Operation()
    87 
    88             Console.ReadKey();
    89         }
    90     }
    91 
    92 }

    六、结果显示

                                    

    七、案例的使用:

    在生活中我们时刻个电脑打交道,那么电脑就是我们补课或缺的一部分,那么我们肯定会给电脑进行添加东西,进行装饰了,

    有外观上的装饰,同样也有内在的性能改变,这就用到了装饰模式了。对于电脑我们可以以性能的装饰来进行实例的演习。

    性能中,我们可以加固态硬盘、内存条等。那么进行演示:

    代码:

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace Test_01
     8 {
     9 
    10     public abstract class Computer
    11     {
    12         public abstract void Show();
    13     }
    14 
    15 
    16     public class HPComputer:Computer
    17     {
    18         public override void Show()
    19         {
    20             Console.WriteLine("以下是对惠普电脑的一系列操作");
    21         }
    22     }
    23 
    24 
    25     public class Decorator:Computer
    26     {
    27         protected Computer computer;
    28 
    29         public void SetCompueter(Computer computer)
    30         {
    31             this.computer = computer;
    32         }
    33 
    34         public override void Show()
    35         {
    36             if(computer!=null)
    37             {
    38                 computer.Show();
    39             }
    40         }
    41     }
    42 
    43 
    44     public class SSD:Decorator
    45     {
    46         public override void Show()
    47         {
    48             base.Show();
    49             Console.WriteLine("我的电脑加装了固态硬盘");
    50         }
    51     }
    52 
    53 
    54     public class Memory : Decorator
    55     {
    56         public override void Show()
    57         {
    58             base.Show();
    59             Console.WriteLine("我的电脑加装了内存条");
    60         }
    61     }
    62 
    63 
    64     class Program
    65     {
    66         static void Main(string[] args)
    67         {
    68             HPComputer decorator = new HPComputer();
    69             SSD ssd = new SSD();
    70             Memory memory = new Memory();
    71 
    72             ssd.SetCompueter(decorator);
    73             memory.SetCompueter(ssd);
    74             memory.Show();
    75             Console.ReadKey();
    76         }
    77     }
    78 }

    运行结果

                                  

     

    八、结语:到底在什么地方使用装饰模式

    当系统需要新功能的时候,是向旧的类中添加新的代码,这些新加的代码通常装饰了原有类的核心职责或主要行为。

    装饰模式是提供了一个非常好的解决方案,他把每个要装饰的功能放在单独的类中,并让这个类包装他所要装饰的对象,因此当需要执行特殊操作行为时,

    客户代码就可以在运行时根据需要有选择的,按顺序的使用装饰功能 包装对象了【DP】

    优点

               1、装饰者模式比继承更灵活

               2、可以通过一种动态的方式来扩展一个对象的功能,在运行时选择不同的装饰器,从而实现不同的行为。

               3、通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合。        

    缺点

               1、会产生很多小对象,增加了系统的复杂性。

               2、更加易于出错,排错也很困难,较为烦琐。

  • 相关阅读:
    堆和栈的区别
    .net中类(class)与结构(struct)的不同
    CTS、CLS、CLR
    C#和.Net的关系
    装箱(boxing)和拆箱(unboxing)
    三层架构
    属性和public字段的区别(调用set方法为一个属性设值,然后用get方法读取出来的值一定是set进去的值吗?)
    override与重载(overload)的区别
    C#中的委托是什么?事件是不是一种委托?事件和委托的关系。
    json转树状菜单栏
  • 原文地址:https://www.cnblogs.com/zhh19981104/p/8034892.html
Copyright © 2020-2023  润新知