• 设计模式——装饰模式


    装饰模式

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

    装饰模式结构

    在装饰模式中各个角色有:

    • 抽象构件(Component)角色: 给出一个抽象接口,以规范准备接收附加责任的对象。
    • 具体构件(Concrete Component)角色:定义一个要接收附加责任的类。
    • 装饰(Decorator)角色:持有一个构件(断肠和)对象的实例,并定义一个与抽象构件接口一致的接口。
    • 具体装饰(Decorator)角色:负责给构件对象 “贴上”附加的责任。

    例子:

    1. 装饰模式动态地为对象附加额外的责任。添加到松树或冷杉树上的装饰品就是装饰模式的例子。灯光、花环、手杖糖果、玻璃装饰品等,都可以添加到树上,让它看起来更喜庆。这些装饰物不会改变圣诞树本身,不管使用什么特殊的装饰物,圣诞树都可以被认作圣诞树。作为附加功能的一个例子,灯的添加允许人们“点亮”圣诞树。
    2. 另一个例子:突击枪本身就是致命武器。但你可以应用某些“装饰”使它更精确、更安静、更具破坏性。

    我们再从代码层面看一个例子:

    使用装饰模式前

    
    package DecoratorPattern.Before;
    
    
    /**
     * 使用装饰模式前
     */
    
    class A {
        public void doIt(){
            System.out.print('A');
        }
    }
    
    class AwithX extends A {
        @Override
        public void doIt() {
            super.doIt();
            doX();
        }
    
        private void doX(){
            System.out.print('X');
        }
    }
    
    class AwithY extends A {
        @Override
        public void doIt() {
            super.doIt();
            doY();
        }
    
        public void doY(){
            System.out.print('Y');
        }
    }
    
    class AwithZ extends A {
        @Override
        public void doIt() {
            super.doIt();
            doZ();
        }
    
        public void doZ() {
            System.out.print('Z');
        }
    }
    
    class AwithXY extends AwithX {
    
        private AwithY obj = new AwithY();
    
        @Override
        public void doIt() {
            super.doIt();
            obj.doY();
        }
    }
    
    class AwithXYZ extends AwithX {
    
        private AwithY obj1 = new AwithY();
        private AwithZ obj2 = new AwithZ();
    
        @Override
        public void doIt() {
            super.doIt();
            obj1.doY();
            obj2.doZ();
        }
    }
    
    public class DecoratorDemo{
        public static void main(String[] args) {
            A[] array = {new AwithX(), new AwithXY(), new AwithXYZ()};
            for (A a: array){
                a.doIt();
                System.out.print(' ');
            }
        }
    }
    
    

    使用装饰模式后

    
    package DecoratorPattern.After;
    
    /**
     * 使用装饰模式后
     */
    
    interface I {
        void doIt();
    }
    
    class A implements I {
    
        @Override
        public void doIt() {
            System.out.print('A');
        }
    }
    
    abstract class D implements I {
        private I core;
    
        public D(I inner) {
            core = inner;
        }
    
        @Override
        public void doIt() {
            core.doIt();
        }
    }
    
    class X extends D {
    
        public X(I inner) {
            super(inner);
        }
    
        @Override
        public void doIt() {
            super.doIt();
            doX();
        }
    
        private void doX() {
            System.out.print('X');
        }
    }
    
    class Y extends D {
    
        public Y(I inner) {
            super(inner);
        }
    
        @Override
        public void doIt() {
            super.doIt();
            doY();
        }
    
        private void doY() {
            System.out.print('Y');
        }
    }
    
    class Z extends D {
    
        public Z(I inner) {
            super(inner);
        }
    
        @Override
        public void doIt() {
            super.doIt();
            doZ();
        }
    
        private void doZ() {
            System.out.print('Z');
        }
    }
    
    public class DecoratorDemo {
        public static void main(String[] args) {
          I[] array = {new X(new A()), new Y(new X(new A())), new Z(new Y(new X(new A())))};
          for (I anArray: array){
              anArray.doIt();
              System.out.print(' ');
          }
        }
    }
    
    
    

    优点:

    1. 装饰模式比静态继续更灵活。与对象的静态继承相比,装饰模式提供了更加灵活地向对象添加职责的方式。可以用添加和分享的方法,用装饰在运行时和删除职责。相比之下,继承机制要求为每个添加的职责创建一个新的子类。这会产生许多新的类,并且会增加系统复杂度。此外,为下个特定的 Component 类提供多个不同的 Decorator 类,这就使得你可以对一些职责进行混合和匹配。
    2. 避免在层次结构高层的类有太多的特征。装饰模式提供了一种”即用即付“的方法来添加职责。它并不试图在一个复杂的可定制的类中支持所有可预见的特征,相反,你可以定义一个简单的类,并且用 Decorator 类给它逐渐地添加功能。可以从简单的部件组合出复杂的功能。这样,应用程序不必为不需要的特征付出代价。

    缺点:

    1. Decorator 与它的 Component 不一样。Decorator 是一个透明的包装。如果我们从对象标识的观点出发,一个被装饰了的组件与这个组件是有差别的,因此,使用装饰时不应该依赖对象标识。
    2. 有许多小对象。采用装饰模式进行系统设计往往会产生许多看上去类似的小对象,这些对象仅仅在它们相互连接的方式上有所不同,而不是它们的类或是它们的属性值有所不同。尽管对天那些了解这些系统的人来说,很容易对它们进行定制,但是很难学习这些系统,排错也很困难。

    模式的简化

    1. 没有抽象的接口 Component 也是可以的,但 ConcreteComponent 就要扮演双重角色。

    1. 没有抽象的 Decorator 也是可以的,只是 ConcreteDecorator 需要扮演双重的角色。

    参考:

    https://sourcemaking.com/design_patterns/decorator

  • 相关阅读:
    POJ 1466 Girls and Boys 黑白染色 + 二分匹配 (最大独立集) 好题
    POJ2226 Muddy Fields 二分匹配 最小顶点覆盖 好题
    POJ 2195 Going Home 最小费用流 裸题
    POJ 3368 Frequent values RMQ 训练指南 好题
    POJ 3187 杨辉三角+枚举排列 好题
    POJ 2393 贪心 简单题
    系统监控
    系统的初始化和服务
    vi与vim
    正文处理命令及tar命令
  • 原文地址:https://www.cnblogs.com/flythinking/p/13703168.html
Copyright © 2020-2023  润新知