• 我也设计模式——13.Decorator




    代码实现如下,注意几点:
    1.Decorator中的Operation()方法是对被修饰对象ConcreteComponent中方法Operation()的封装
    2.ConcreteDecorator中的Operation()方法是对其父类Operation()方法的封装,同时加入一些额外的新方法
    3.ConcreteDecorator中的构造函数负责将修饰与被修饰对象链接在一起,如下图:

        public interface Component
        
    {
            
    void Operation();
        }


        
    public class ConcreteComponent : Component
        
    {
            
    public void Operation()
            
    {
                Console.WriteLine(
    "Old Function");
            }

        }


        
    public class Decorator : Component
        
    {
            
    protected Component op;

            
    public virtual void Operation()
            
    {
                op.Operation();
            }

        }


        
    public class ConcreteDecoratorA : Decorator
        
    {
            
    public ConcreteDecoratorA(Component op)
            
    {
                
    this.op = op;
            }


            
    private void DoSomeThing1()
            
    {
                Console.WriteLine(
    "New Function 1");
            }



            
    public override void Operation()
            
    {
                op
    .Operation();
                DoSomeThing1();
            }

        }


        
    public class ConcreteDecoratorB : Decorator
        
    {
             
    public ConcreteDecoratorB(Component op)
            
    {
                
    this.op = op;
            }


            
    private void DoSomeThing2() 
            
    {
                Console.WriteLine(
    "New Function 2");
            }


            
    public override void Operation()
            
    {
                
    base.Operation();
                DoSomeThing2();
            }


        }


        
    public class Client
        
    {
            
    public static void Main(string[] args)
            
    {
                ConcreteComponent c 
    = new ConcreteComponent();
                ConcreteDecoratorA d1 
    = new ConcreteDecoratorA(c);
                ConcreteDecoratorB d2 
    = new ConcreteDecoratorB(d1);           

                d2.Operation();
            }

        }

    装饰者与被装饰者具有相同的接口,从而动态增加的功能不会破坏已有的接口,即修有一个对象后,其接口不发生变化
    透明且动态的方式增加单个对象的功能
    所谓透明,即用户仍可以直接访问被修饰者
    另外一种增加功能的方法是继承
    使用时保持被修饰者的功能单一,从而进行修饰的时候,可以组合出更多的功能,结构灵活——即被修饰者“原子化”

    Decorator的缺点是会产生许多小对象。

    可以使用Decorator来给抽象工厂增加新方法,以为DB增加记录日志功能为例:

    LogDB是这么写的:
        public class LogDB : clsAbstractDB
        
    {
            
    private clsAbstractDB myDB;

            
    public clsAbstractDB DB
            
    {
                
    get return myDB; }
                
    set { myDB = value; }
            }


            
    public override void Open()
            
    {
                myDB.Open();
                Record(
    "
    Open");
            }


            
    public override DataTable ExecSQL(string strSQL)
            
    {
                DataTable dt 
    = myDB.ExecSQL(strSQL);
                Record(
    "ExecSQL: " + strSQL);

                  return dt;
            }


            
    //新方法 记录日志
            private void Record(string strRecord)
            

                
    //再次记录日志
            }

        }

    经典的BufferStream:


    由于在.NET中已经实现了框架,我们只看怎么使用:
    Buffered的作用是为另一流上的读写操作添加一个缓冲层,从而提高读取和写入性能
            public void BufferedStreamMethod(string path)
            
    {
                FileStream fs 
    = File.Create(path);
                Stream bs 
    = new BufferedStream(fs);

                AddText(bs, 
    "Hello!");
            }


            
    public void AddText(Stream fs, string value)
            
    {
                
    byte[] info = new UTF8Encoding(true).GetBytes(value);
                fs.Write(info, 
    0, info.Length);
            }

    装饰模式与策略模式,两者能达到同样的效果——增加新功能,对比以下UML图,
        

        二者的不同是,Decorator是从小到大,层层包装;Strategy是先制作大粒度对象,其中包括不变的对象和可变的部分。

    微软的AJAX.NET控件是基于Decorator实现的,原来的TextBox等基本控件仍然可以使用,然而我们可以使用新的控件绑定到这个TextBox上,从而增加新的功能。
  • 相关阅读:
    Git 一些常用命令
    Opengl VS2008开发环境
    用 HTML5 给 iPad,iPhone 打造速度超快的应用_HTML5研究小组
    理解CSS3 transform中的Matrix(矩阵) « 张鑫旭鑫空间鑫生活
    Google Dremel 原理 如何能 3 秒分析 1PB 开源中国社区
    Perl:过滤注释
    HTML5 History API实现无刷新跳转 蓝飞技术部落格 —— 关注前沿,追求卓越。
    OPENGL编程指南
    Perl : Quantifier follows nothing in regex; marked by
    .js文件无法运行的方法
  • 原文地址:https://www.cnblogs.com/Jax/p/913140.html
Copyright © 2020-2023  润新知