装饰模式(未完成)

装饰模式

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

  • Component,定义了一个对象接口,可以给这些对象动态的添加职责。
  • ConcreteComponent,定义了一个具体的对象,也可以给这个对象添加一些职责。
  • Decorator,装饰抽象类,继承了Component,从外类来扩展Component类的功能,但对于Component来说,其无需知道Decorator的存在。
  • ConcreteDecorator,就是具体的装饰对象,用来给Component添加各种功能。

装饰模式结构图

2.4.x 案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

public class Test {
public static void main(String[] args) {
//换装系统
Person zs = new Person("张三");
System.out.println("-------------------第一种装扮");
Finery dtx = new TShirtsFinery();
Finery kk = new BigTrouserFinery();
Finery ydx = new SneakerFinery();
dtx.show();
kk.show();
ydx.show();
zs.show();
System.out.println("-------------------第二种装扮");
Finery xz = new SuitFinery();
Finery ld = new TieFinery();
Finery px = new LeatherShoesFinery();
xz.show();
ld.show();
px.show();
zs.show();

//存在问题有:每次都只能单独的穿一件衣服
}
}

//服饰抽象类
public abstract class Finery {
public abstract void show();
}

public class BigTrouserFinery extends Finery {
@Override
public void show() {
System.out.println("垮裤");
}
}

......

public class TShirtsFinery extends Finery {
@Override
public void show() {
System.out.println("大T恤");
}
}

public class Person {
private String name;

public Person() {
}

public Person(String name) {
this.name = name;
}

public void show(){
System.out.println("装扮——" + name);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
    public static void main(String[] args) {
//装饰模式
System.out.println("-------------------第一种装扮");
TShirtsDecorator dtxDecorator = new TShirtsDecorator();
BigTrouserDecorator kkDecorator = new BigTrouserDecorator();
SneakerDecorator ydxDecorator = new SneakerDecorator();

dtxDecorator.setComponent(zs);
kkDecorator.setComponent(dtxDecorator);
ydxDecorator.setComponent(kkDecorator);
ydxDecorator.show();

System.out.println("-------------------第二种装扮");
SuitDecorator xzDecorator = new SuitDecorator();
TieDecorator ldDecorator = new TieDecorator();
LeatherShoesDecorator pxDecorator = new LeatherShoesDecorator();

xzDecorator.setComponent(zs);
ldDecorator.setComponent(xzDecorator);
pxDecorator.setComponent(ldDecorator);
pxDecorator.show();
}

public class FineryDecorator extends Person {
protected Person component;

public FineryDecorator() {
}

public void setComponent(Person component) {
this.component = component;
}

@Override
public void show() {
if(component != null){
component.show();
}
}
}

public class BigTrouserDecorator extends FineryDecorator {
@Override
public void show() {
System.out.println("垮裤");
super.show();
}
}

......

public class TShirtsDecorator extends FineryDecorator {
@Override
public void show() {
System.out.println("大T恤");
super.show();
}
}

2.4.x 代码结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
public abstract class Component {
public abstract void operation();
}

public class ConcreteComponent extends Component {
@Override
public void operation() {
System.out.println("具体对象操作");
}
}

public class ConcreteDecoratorA extends Decorator {
private String addedState;

@Override
public void operation() {
super.operation();//先运行原Component的operation
addedState = "New State";//再执行本类的功能如addedState,相当于对原Component进行了装饰
System.out.println("具体装饰对象A的操作");
}
}

public class ConcreteDecoratorB extends Decorator {

@Override
public void operation() {
super.operation();//先运行原Component的operation
addedBehavior();//再执行本类的功能如addedBehavior(),相当于对原Component进行了装饰
System.out.println("具体装饰对象B的操作");
}

private void addedBehavior(){//本类独有方法,区别于ConcreteDecoratorA
System.out.println("addedBehavior");
}
}

public abstract class Decorator extends Component {
protected Component component;

public void setComponent(Component component) {//设置Component
this.component = component;
}

@Override
public void operation() {//重写operation(),实际执行仍是component.operation()
if(component != null){
component.operation();
}
}
}

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

//首先用ConcreteComponent实例化对象c,然后用ConcreteDecoratorA实例化对象d1来包装c
d1.setComponent(c);
//再用ConcreteDecoratorB实例化对象d2包装d1
d2.setComponent(d1);
//最终执行d2的operation()
d2.operation();
}
}

  若是只有一个ConcreteComponent类而没有抽象的Component类,那么Decorator就可以是ConcreteComponent的一个子类。同样道理,若只有一个ConcreteDecorator类,那么就没必要建立一个单独的Decorator类,而可以把Decorator和ConcreteDecorator的责任合并成一个类。

  装饰模式是为已有功能动态的添加更多功能的一种方式。过去当系统需要新功能时,是向旧的类中添加新的代码。这些新加的代码通常装饰了原有类的核心职责或主要行为,它们在主类中加入了新的字段,新的方法和新的逻辑,从而增加了主类的复杂度,而这些新加入的东西仅仅是为了满足一些只在某种特定情况下才会执行的特殊行为的需要。这时装饰模式提供了一个非常好的解决方案,它把每个要装饰的功能放在单独的类中,并让这个类包装它所需要装饰的对象,因此当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择地、按顺序的使用装饰功能包装对象了。

  装饰模式的优点就在于把类中的装饰功能切分出去,这样可以简化原有的类,有效的把类的核心职责和装饰功能区分开,而且可以去除相关类中重复的装饰逻辑。


参考:

🔗 《设计模式:可复用面向对象软件的基础》
🔗 《大话设计模式》