zoukankan      html  css  js  c++  java
  • 装饰者模式--穿什么有这么重要?

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

      装饰者模式是为已有功能动态地添加更多功能地一种方式。当系统需要新功能的时候,是向旧的类中添加新的代码。这些新加的代码通常装饰了原有类的核心职责或主要行为。装饰者模式他把要装饰的功能放在单独的类中,并让这个类包装他所需要装饰的对象,因此,当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象了。(核心思想)

      装饰者模式是为已有功能动态地添加更多功能的一种方式。

      装饰者模式的优点:把类中的装饰功能从类中搬移出去,这样可以简化原有的类。有效地把类的核心职责和装饰功能区分开了,而且可以去除相关类中重复的装饰逻辑。
      装饰模式的装饰顺序很重要,最理想的情况,是保证装饰类之间彼此独立,这样他们就可以以任意的顺序进行组合了。

    1 //Component是定义一个对象接口,可以给这些对象动态地添加职责
    2 public abstract class Component {
    3     public abstract void operation();
    4 }
     1 /**
     2  * 定义了一个具体的对象,也可以给这个对象添加一些职责,一般不在这里添加
     3  * @author 贤元
     4  *
     5  */
     6 public class ConcreteComponent extends Component {
     7 
     8     @Override
     9     public void operation() {
    10         System.out.println("具体对象的操作---被装饰的对象");
    11     }
    12 
    13 }
     1 /**
     2  * 装饰抽象类,继承了Component,从外类来扩展Component类的功能,但
     3  *     对于Component来说,是无需知道Decorator的存在的
     4  * @author 贤元
     5  *
     6  */
     7 public abstract class Decorator extends Component {
     8     
     9     //被装饰者对象的句柄
    10     protected Component component;
    11     
    12     //设置component,设置被装饰者
    13     public void setComponent(Component component) {
    14         this.component = component;
    15     }
    16 
    17 
    18     //重写operation,实际执行的是Component的operation
    19     @Override
    20     public void operation() {
    21         if(component!=null){
    22             component.operation();
    23         }
    24     }
    25 
    26 }
     1 //装饰者A  就是具体的装饰对象,起到给Component添加职责的功能
     2 public class ConcreteDecorationA extends Decorator{
     3     
     4     //本类独有功能,区别于ConcreteDecorationB
     5     private String addedState;
     6     
     7     @Override
     8     public void operation() {
     9         //首先运行原Component的Operation(),再执行本类的功能,如addedState,相当于对原Component进行了装饰
    10         super.operation();
    11         addedState = "New StateA新状态--装饰者A";
    12         System.out.println("具体装饰对象A的操作--装饰者A");
    13     }
    14 }
     1 //装饰者B
     2 public class ConcreteDecorationB extends Decorator {
     3     @Override
     4     public void operation() {
     5         //首先运行原Component的Operation(),再执行本类的功能,如addedState,相当于对原Component进行了装饰
     6         super.operation();
     7         addedBehavior();
     8         System.out.println("具体装饰对象B的操作--装饰者B");
     9     }
    10     
    11     //本类独有的方法,区别于ConcreteDecorationA
    12     private void addedBehavior(){
    13         System.out.println("装饰者B独有的装饰--装饰者B");
    14     }
    15 }

    测试类:

     1 //客户端代码
     2 public class Test {
     3     public static void main(String[] args) {
     4         //c是被装饰者
     5         ConcreteComponent c = new ConcreteComponent();
     6         //装饰者d1
     7         ConcreteDecorationA d1 = new ConcreteDecorationA();
     8         //装饰者d2
     9         ConcreteDecorationB d2 = new ConcreteDecorationB();
    10          
    11         /**
    12          * 装饰的方法是:首先用ConcreteComponent实例化对象c,然后
    13          *     用ConcreteDecoratorA的实例化对象d1来包装c,
    14          *     再用ConcreteDecorationB的对象d2包装d1,最终执行d2的Operation();
    15          */
    16         d1.setComponent(c);
    17         d2.setComponent(d1);
    18         d2.operation();
    19         //是有执行顺序的,执行的顺序由客户端代码顺序决定
    20     }
    21 }

      装饰者模式是利用setComponent来对对象进行包装的。这样每个装饰对象的实现就和如何使用这个对象分开了,每个装饰对象只关心自己的功能,不需要关心如何被添加到对象类当中。

      学习模式要善于变通,如果只有一个ConcreteComponent类而没有抽象的Component类,那么Decorator类可以是ConcreteComponent的一个子类。同样道理,如果只有一个ConcreteDecorator类,那么久没有必要建立一个单独的Decorator类,而可以把Decorator和ConcreteDecorator的责任合并成一个类。

    试结果:

    具体对象的操作---被装饰的对象
    具体装饰对象A的操作--装饰者A
    装饰者B独有的装饰--装饰者B
    具体装饰对象B的操作--装饰者B

    UML图:

         Component是定义一个对象接口,可以给这些对象动态地添加职责,ConcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职责,如果后期添加的话会违反开-闭原则。Decorator,装饰抽象类,继承了Component,从外类来扩展Component类的功能,但对于Component来说,是无需知道Decorator的存在的,至于ConcreteComponent就是具体的装饰对象,起到给Component添加职责的功能。

    不能只满足于写完代码运行结果正确就完事,时常考虑如何让代码更加简练更加容易维护、容易扩展和复用,只有这样才可以真正得到提高 --《来自大话设计模式》
  • 相关阅读:
    [转]
    Linux
    [转]
    [转]
    Linux 高级网络编程
    [转]
    [译]- 6-1 排列窗体上的控件(Laying Out Widgets on a Form)
    [转]
    [转]
    the thread has exited with code -1073741819
  • 原文地址:https://www.cnblogs.com/lixianyuan-org/p/9473971.html
Copyright © 2011-2022 走看看