Home 装饰器模式
Post
Cancel

装饰器模式

Decorator Pattern 对象结构型模式

意图

动态地给一个对象添加一些额外的职责。就增加功能而言,Decorator 模式比生成子类更加灵活

结构

装饰器

其中:

  • Component 定义一个对象接口,可以给这些对象动态地添加职责
  • ConcreteComponent 定义一个对象,可以给这个对象添加一些职责
  • Decorator 维持一个指向 Component 对象的指针,并定义一个与 Component 接口一致的接口
  • ConcreteDecorator 向组件添加职责

适用性

Decorator 模式适用于:

  • 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责
  • 处理那些可以撤销的职责
  • 当不能采用生成子类的方式进行扩充时,一种情况是,可能有大量独立的拓展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是,由于类定义被隐藏,或类定义不能用于生成子类

例子 1

某咖啡店当卖咖啡时,可以根据顾客的要求在其中加入各种配料,咖啡店会根据所加入的配料来计算费用。咖啡店所供应的咖啡及配料的种类和价格如下表所示

装饰器模式-例子-图1

现采用装饰器模式来实现计算费用的功能,得到如下类图

装饰器模式-例子-图2

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
import java.util.*;

    abstract class Beverage { // 饮料
    String description = "Unknown Beverage";
    public String getDescription() { return description; }
    public abstract int cost();
}

abstract class CondimentDecorator extends Beverage { // 配料
    Beverage beverage;
}

class Espresso extends Beverage { // 蒸馏咖啡
    private final int ESPRESSO_PRICE = 25;
    public Espresso() { description = "Espresso"; }
    public int cost() { return ESPRESSO_PRICE; }
}

class DarkRoast extends Beverage { // 深度烘焙咖啡
    private final int DARKROAST_PRICE = 20;
    public DarkRoast() { description = "DarkRoast"; }
    public int cost() { rcturn DARKROAST PRICE; }
}

class Mocha extends CondimentDecorator { // 摩卡
    private final int MOCHA_PRICE = 10;
    public Mocha (Beverage beverage) { this.beverage = beverage; }
    public String getDescription() {
        return beverage.getDescription() + ", Mocha";
    }
    public int cost() { return MOCHA_PRICE + beverage.cost(); }
}

class Whip extends CondimentDecorator { // 奶泡
    private final int WHIP_PRICE = 8;
    public Whip (Beverage beverage) { this.beverage = beverage; }
    public String getDescription() {
        return beverage.getDescription() + ", Whip";
    }
    public int cost() { return WHIP_PRICE + beverage.cost(); }
}

public class Coffee {
    public static void main(String args[]) {
        Beverage beverage = new DarkRoast();
        beverage = new Mocha(beverage);
        beverage = new Whip(beverage);
        System.out.println(beverage.getDescription() +" ¥"+ beverage.cost());
    }
}

例子 2

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 class DecoratorPattern {
    public static void main(String[] args) {
        Person p = new Student("Mike");
        p.Operation();

        System.out.println("\n--------------------");

        p = new DecoratorA(p);
        p.Operation();

        System.out.println("\n--------------------");

        p = new DecoratorB(p);
        p.Operation();

        // No.2
        Person p2 = new DecoratorB(new Student("Jane"));
    }
}

abstract class Person{
    protected String name;

    public abstract void Operation();
}

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

    @Override
    public void Operation(){
        System.out.print(name + " Study");
    }
}

abstract class Decorator extends Person{
    protected Person person;

}

class DecoratorA extends Decorator{
    public DecoratorA(Person person){
        this.person = person;
    }

    @Override
    public void Operation() {
        person.Operation();
        System.out.print(" Play");
    }
}

class DecoratorB extends Decorator{
    public DecoratorB(Person person){
        this.person = person;
    }

    @Override
    public void Operation() {
        person.Operation();
        System.out.print(" Exam");
    }
}
This post is licensed under CC BY 4.0 by the author.

组合模式

外观模式