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

    作者:TerryLee  创建于:2006-03-01 出处:http://terrylee.cnblogs.com/archive/2006/03/01/340592.html  收录于:2013-02-28

    结构图


     

    意图


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

    适用性


    • 需要扩展一个类的功能,或给一个类增加附加责任。
    • 需要动态地给一个对象增加功能,这些功能可以再动态地撤销。
    • 需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变得不现实。

    实现代码


     1 using System;
     2 public abstract class Log
     3 {
     4     public abstract void Write(string log);
     5 }
     6 public class DatabaseLog : Log
     7 {
     8     public override void Write(string log)
     9     {
    10         Console.WriteLine("记录到数据库中");
    11     }
    12 }
    13 public class TextFileLog : Log
    14 {
    15     public override void Write(string log)
    16     {
    17         Console.WriteLine("记录到文本文件中");
    18     }
    19 }
    20 public abstract class LogWrapper : Log  //继承,组合
    21 {
    22     private Log _log;
    23     public LogWrapper(Log log)
    24     {
    25         _log = log;
    26     }
    27     public override void Write(string log)
    28     {
    29         _log.Write(log);
    30     }
    31 }
    32 public class LogErrorWrapper : LogWrapper
    33 {
    34     public LogErrorWrapper(Log _log): base(_log)
    35     { }
    36     public override void Write(string log)
    37     {
    38         SetError(); //......功能扩展
    39         base.Write(log);
    40     }
    41     public void SetError()
    42     {
    43         Console.WriteLine("实现了记录错误严重级别");
    44     }
    45 }
    46 public class LogPriorityWrapper : LogWrapper
    47 {
    48     public LogPriorityWrapper(Log _log): base(_log)
    49     { }
    50     public override void Write(string log)
    51     {
    52         SetPriority(); //......功能扩展
    53         base.Write(log);
    54     }
    55     public void SetPriority()
    56     {
    57         Console.WriteLine("实现了记录优先级别");
    58     }
    59 }
    60 public class Program
    61 {
    62     public static void Main(string[] args)
    63     {
    64         Log log = new DatabaseLog();
    65         LogWrapper lew1 = new LogErrorWrapper(log);
    66         //扩展了记录错误严重级别
    67         lew1.Write("Log Message");
    68         LogPriorityWrapper lpw1 = new LogPriorityWrapper(log);
    69         //扩展了记录优先级别
    70         lpw1.Write("Log Message");
    71         LogWrapper lew2 = new LogErrorWrapper(log);
    72         LogPriorityWrapper lpw2 = new LogPriorityWrapper(lew2); //这里是lew2
    73         //同时扩展了错误严重级别和优先级别
    74         lpw2.Write("Log Message");
    75         Console.Read();
    76     }
    77 }

    我们分析一下这样会带来什么好处?

    1)首先对于扩展功能已经实现了真正的动态增加,只在需要某种功能的时候才进行包装;
    2)其次,如果再出现一种新的扩展功能,只需要增加一个对应的包装子类(注意:这一点任何时候都是避免不了的),而无需再进行很多子类的继承,不会出现子类的膨胀,同时Decorator模式也很好的符合了面向对象设计原则中的“优先使用对象组合而非继承”和“开放-封闭”原则。

    效果及实现要点


    1.Component类在Decorator模式中充当抽象接口的角色,不应该去实现具体的行为。而且Decorator类对于Component类应该透明,换言之Component类无需知道Decorator类,Decorator类是从外部来扩展Component类的功能。

    2.Decorator类在接口上表现为is-a Component的继承关系,即Decorator类继承了Component类所具有的接口。但在实现上又表现为has-a Component的组合关系,即Decorator类又使用了另外一个Component类。我们可以使用一个或者多个Decorator对象来“装饰”一个Component对象,且装饰后的对象仍然是一个Component对象。
    3.Decortor模式并非解决“多子类衍生的多继承”问题,Decorator模式的应用要点在于解决“主体类在多方向上的扩展功能”——是为“装饰”的含义。
    4.对于Decorator模式在实际中的运用可以很灵活。如果只有一个ConcreteComponent类而没有抽象的Component类,那么Decorator类可以是ConcreteComponent的一个子类。如果只有一个ConcreteDecorator类,那么就没有必要建立一个单独的Decorator类,而可以把Decorator和ConcreteDecorator的责任合并成一个类。
    5.Decorator模式的优点是提供了比继承更加灵活的扩展,通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合。
    6.由于使用装饰模式,可以比使用继承关系需要较少数目的类。使用较少的类,当然使设计比较易于进行。但是,在另一方面,使用装饰模式会产生比使用继承关系更多的对象。更多的对象会使得查错变得困难,特别是这些对象看上去都很相像。

  • 相关阅读:
    Linux标准C头文件和内核头文件的理解
    linux GCC编译C程序的问题
    C#类型反射、晚期绑定、特性编程的使用背景与分析
    linux下C#开发mongoDB
    C中“指针和数组”引发的探索一
    C#学习记录
    linux下Apache+PHP+mysql+phpMyAdmin源码包安装配置
    基于mongoDB和C#分布式海量文件存储实验
    C中指针和数组引发的探索二
    算法研究学习一(用C和C#实现)
  • 原文地址:https://www.cnblogs.com/Ming8006/p/2937325.html
Copyright © 2011-2022 走看看