设计模式系列:装饰器模式

概念

动态地将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

实现

  • 类图:

图片

Money:

1
2
3
4
5
6
7
8
9
10
11
package com.littlehui.design.decorator;

/**
* Created by littlehui on 2018/1/15.
*/
public interface Money {

public Double totalMoney();

public String getDescription();
}

Wages:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.littlehui.design.decorator;

/**
* Created by littlehui on 2018/1/15.
*/
public class Wages implements Money {

public Double totalMoney() {
return 10D;
}

public String getDescription() {
return "基础工资,";
}
}

Reward:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.littlehui.design.decorator;

/**
* Created by littlehui on 2018/1/15.
*/
public class Reward implements Money {

Money money;

public Reward(Money money) {
this.money = money;
}

public Double totalMoney() {
return 4d + money.totalMoney();
}

public String getDescription() {
return "加上额外奖励" + money.getDescription();
}
}

Bonuses:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.littlehui.design.decorator;

/**
* Created by littlehui on 2018/1/15.
*/
public class Bonuses implements Money {

Money money;

public Bonuses(Money money) {
this.money = money;
}

public Double totalMoney() {
return 5d + money.totalMoney();
}

public String getDescription() {
return "加上奖金" + money.getDescription();
}
}

Client:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.littlehui.design.decorator;

/**
* Created by littlehui on 2017/11/9.
*/
public class Client {

public static void main(String[] args) {
Money wages = new Wages();
//奖金装饰它
wages = new Bonuses(wages);
//额外奖励装饰它
wages = new Reward(wages);
System.out.println("工资:" + wages.getDescription() + wages.totalMoney());
}
}

场景

Java.io包里就使用了装饰器。
BufferedInputStream及LineNumberInputStream都扩展自FilterInputStream,而FilterInputStream是一个抽象的装饰类。

总结

装饰器模式体现了设计模式里的 开放-关闭原则。

  1. 装饰者和被装饰者对象有相同的父类
  2. 可以使用一个或者多个装饰者包装一个对象。
  3. 在任何需要原始对象他们可以相互替换。
  4. 装饰者可以在所委托被装饰者的行为之前与/或之后,加上自己的行为,以达到特定的目的。
  5. 对象可以在任何时候被装饰,所以可以在运行时动态,不限量地使用。