现在的位置: 首页 > 综合 > 正文

设计模式 – 装饰 Decorator

2018年04月07日 ⁄ 综合 ⁄ 共 1883字 ⁄ 字号 评论关闭

1. 意图

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

2. 别名

包装器 Wrapper

3. 动机

给某个对象而不是整个类添加一些功能。

4. 适用性

在不影响其他对象的情况下,以动态,透明的方式给单个对象添加职责。

处理那些可以撤销的职责。

当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。

5. 类图

6. 代码

    class Program
    {
        static void Main(string[] args)
        {
            IWindow window = new HorizontalScrollbarDecorator(new VerticalScrollbarDecorator(new SimpleWindow()));
            window.Draw();
        }
    }

    interface IWindow
    {
        void Draw();
        string GetDescription();
    }

    class SimpleWindow : IWindow
    {
        public void Draw()
        {
            Console.WriteLine("draw a simple window");
        }

        public string GetDescription()
        {
            return "I am a simple window";
        }
    }

    class WindowDecorator : IWindow
    {
        protected IWindow iWindow = null;

        public WindowDecorator(IWindow iWindow)
        {
            this.iWindow = iWindow;
        }

        public void Draw()
        {
            iWindow.Draw();
        }

        public string GetDescription()
        {
            return iWindow.GetDescription();
        } 
    }

    class HorizontalScrollbarDecorator : WindowDecorator
    {
        public HorizontalScrollbarDecorator(IWindow iWindow)
            : base(iWindow)
        { 
        }

        public void Draw()
        {
            base.Draw();
            DrawHorizontalScrollbarDecorator();
        }

        private void DrawHorizontalScrollbarDecorator()
        {
            Console.WriteLine("draw a horizontal scrollbar");
        }

        public string GetDescription()
        {
            string result = base.GetDescription();
            result += "a window with horizontal scrollbar";
            return result;
        } 
    }

    class VerticalScrollbarDecorator : WindowDecorator
    {
        public VerticalScrollbarDecorator(IWindow iWindow)
            : base(iWindow)
        { 
        }

        public void Draw()
        {
            base.Draw();
            DrawVerticalScrollbarDecorator();
        }

        private void DrawVerticalScrollbarDecorator()
        {
            Console.WriteLine("draw a vertical scrollbar");
        }

        public string GetDescription()
        {
            string result = base.GetDescription();
            result += "a window with vertical scrollbar";
            return result;
        }
    }

8. 效果

Decorator模式的优点和缺点

1) 比静态继承更灵活

2) 可以避免在层次结构的高层类有太多的特性

3) Decorator类和Component类还是不一样的

4) 太多的Decorator容易产生很多小对象

9. 讨论

Decorator可以在运行时为对象动态的添加职责,关键点就在于Decorator与ConcreteComponen具有同样的接口

Decorator和Composite模式的区别在于Composite模式的一个类具有容器的特性,因此可以体现部分-整体的关系, 并且没有子类

Decorator的装饰类可以有子类,子类就是具体的装饰者

公共的Component应当尽量保持简单,它应当集中于定义接口而不是存储数据

抱歉!评论已关闭.