1 package decoration;
 2 
 3 /**@author cby
 4  * 装饰模式模板
 5  * 装饰模式:
 6  * 动态地给一个对象添加一些额外的职责,就增强功能来说,装饰模式比生成子类更为灵活
 7  *
 8  * 总结:一个非常巧妙的设计模式,正如它的名字:装饰模式
 9  * 我们在穿一件衣服的时候是会按照一种顺序来穿的,先穿内裤再穿外裤
10  * 如果反着来的话就不对了(超人除外)
11  * 而这种设计模式正体现了这种要求有顺序的方法
12  *
13  * 几个细节:
14  *  我们为什么可以确保顺序呢,因为在ConcreteDecorator的operation方法里面我们调用的
15  * 是父类的operation方法,然后再调用自己的独特的方法。
16  * Decorator类中的setComponent方法是用来设置传入的真正对象的,用来在operation中调用
17  * 比如说这里 我们调用的是d2的operation方法,d2再去调用父类的operation方法,而父类中传入的
18  * 是d1对象,所以调用的是d1的operation方法,d1再去调用父类的operation方法,而它的父类中
19  * 传入的是ConcreteComponent的对象,所以调用的是ConcreteComponent对象的方法后再调用
20  * d1本身的方法,再调用d2本身的方法
21  * 所以我们在main函数中只调用了一个对象的operation方法,但是却出现了三行字,
22  * 顺序和我们setComponent的顺序一致
23  * 可以说是非常的巧妙了
24  *
25  */
26 
27 /**定义了一个对象接口,可以动态添加职责
28  *
29  */
30 abstract class Component
31 {
32     public abstract void operation();
33 }
34 
35 class ConcreteComponent extends Component
36 {
37     @Override
38     public void operation() {
39         System.out.println("具体对象的操作");
40     }
41 }
42 
43 public abstract class DecorationTemplate extends Component{
44     protected Component component;
45 
46     /**
47      * 设置component,体现了多态
48      *
49      */
50     public void setComponent(Component component)
51     {
52         this.component = component;
53     }
54 
55     /**
56      * 重写了operation() 实际执行的是component的operation
57      *
58      */
59     @Override
60     public void operation() {
61         if(component != null)
62         {
63             component.operation();
64         }
65     }
66 }
67 class ConcreteDecoratorA extends DecorationTemplate
68 {
69     /**
70      * 本类独有的功能,用于区别ConcreteDecoratorB
71      */
72     private String addedState;
73 
74     @Override
75     public void operation() {
76         super.operation();
77         addedState = "New State";
78         System.out.println("具体装饰对象A的操作");
79     }
80 }
81 
82 class ConcreteDecoratorB extends DecorationTemplate
83 {
84     @Override
85     public void operation() {
86         super.operation();
87         addedBehavior();
88         System.out.println("具体装饰对象B的操作");
89     }
90 
91     private void addedBehavior()
92     {
93 
94     }
95 }

main函数:

     ConcreteComponent c =new ConcreteComponent();
        ConcreteDecoratorA d1 = new ConcreteDecoratorA();
        ConcreteDecoratorB d2 = new ConcreteDecoratorB();

        d1.setComponent(c);
        d2.setComponent(d1);
        d2.operation();

控制台输出:

具体对象的操作
具体装饰对象A的操作
具体装饰对象B的操作

 

设计模式----装饰模式_main函数

这个模式在调用operation方法的时候特别的复杂,一定要好好体会,多看几遍!

下面我来举一个具体的例子:穿衣服

 1 package decoration;
 2 
 3 /**
 4  * @author cby
 5  * 学习设计模式要善于变通,如果只有一个ConcreteComponent类而没有抽象的Component类
 6  * 那么Decorator就可以是ConcreteComponent的一个子类。
 7  * 同样道理,如果只有一个ConcreteDecorator类,那就没有必要建立一个单独的Decorator类
 8  * 而可以把Decorator和ConcreteDecorator的责任合并成一个类
 9  */
10 
11 class Person
12 {
13     private String name;
14     public Person()
15     {}
16     public Person(String name)
17     {
18         this.name = name;
19     }
20 
21     public void show()
22     {
23         System.out.println("人类高质量" + this.name);
24     }
25 }
26 
27 public class DecorationExample extends Person
28 {
29     protected Person component;
30 
31     public void Decorate(Person component)
32     {
33         this.component = component;
34     }
35 
36     @Override
37     public void show()
38     {
39         if(component != null)
40         {
41             component.show();
42         }
43     }
44 }
45 class Suit extends DecorationExample
46 {
47     @Override
48     public void show() {
49         System.out.print("西装  ");
50         super.show();
51     }
52 }
53 
54 class Tie extends DecorationExample
55 {
56     @Override
57     public void show() {
58         System.out.print("领带  ");
59         super.show();
60     }
61 }
62 
63 class LeatherShoes extends  DecorationExample{
64     @Override
65     public void show() {
66         System.out.print("皮鞋  ");
67         super.show();
68     }
69 }
70 
71 class Trouser extends  DecorationExample{
72     @Override
73     public void show() {
74         System.out.print("西裤  ");
75         super.show();
76     }
77 }

main函数:

public static void main(String[] args) {

        Person cby = new Person("cby");

        LeatherShoes leatherShoes = new LeatherShoes();
        Trouser trouser = new Trouser();
        Tie tie = new Tie();
        Suit suit = new Suit();

        leatherShoes.Decorate(cby);
        trouser.Decorate(leatherShoes);
        tie.Decorate(trouser);
        suit.Decorate(tie);

        suit.show();

    }

控制台输出:

西装  领带  西裤  皮鞋  人类高质量cby

 

设计模式----装饰模式_ide_02

 

 

让我来细细拆分研究代码:

leatherShoes.Decorate(cby);

在实例化对象之后我们就正式开始装饰了,首先我们把leathershoes对象中的component赋成cby

然后继续赋值

trouser.Decorate(leatherShoes);
tie.Decorate(trouser);
suit.Decorate(tie);

赋值完成之后开始调用,然后关键的点就来了

suit.show();

我们调用suit的show方法,他会首先打印西装,再去调用父类中的show方法

class Suit extends DecorationExample
{
     @Override
     public void show() {
     System.out.print("西装  ");
     super.show();
     }
 }

我们再去找他的父类DecorationExample就可以发现这个类调用的是类中Person类型的成员component的show方法

而我们之前设置过这个component了,就是tie,于是tie再去调用show方法。

同理首先打印领带,再调用trouser对象的show方法,这样循环下去

一直到cby,调用cby的show方法,而cby的show方法是打印 "人类高质量cby" 

就结束了

这就是全过程