设计模式3 - 装饰器模式

定义
装饰者模式允许向一个现有的对象添加新的功能,同时又不改变其结构。就是创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

关键点:
1. 装饰者和被装饰对象有相同的超类型
2. 你可以使用一个或多个装饰者来包装一个对象
3. 既然装饰者和被装饰对象有相同的超类型,所以在任何需要原始对象(被包装的)的场合,可以用装饰者对象代替它
4. 装饰者可以在所委托被装饰者的行为之前或之后,加上自己的行为,以达到特定的目的
5. 对象可以在任何时候被装饰,所以可以在运行时动态地、不限量地用你喜欢的装饰者来装饰对象

组成
Component:充当抽象的被装饰者
ConcreteComponent:具体的组件,继承自Component,
Decorator:装饰者抽象类,含有一个被装饰者的引用
ConcreteDecorator:具体装饰者类

适用场景
不想修改原有类的基础上,却想要动态添加新的功能。

例子

(Beverage.java)
public abstract class Beverage {

    protected String description = "unknown beverage";

    public String getDescription(){
        return description;
    }

    public abstract double cost();
}

(Espresso.java)
public class Espresso extends Beverage{

    public Espresso() {
        description = "Espresso";
    }

    @Override
    public double cost() {
        return 1.99;
    }
}

(CondimentDecorator.java)
public abstract class CondimentDecorator extends Beverage{

    protected Beverage beverage;

    public CondimentDecorator(Beverage beverage){
        this.beverage = beverage;
    }

    public double cost() {
        return beverage.cost();
    }

    public abstract String getDescription();
}

(Milk.java)
public class Milk extends CondimentDecorator{
    public Milk(Beverage beverage) {
        super(beverage);
    }

    @Override
    public String getDescription() {
        return beverage.getDescription() + " + milk";
    }

    public double cost() {
        return 1.3 + beverage.cost();
    }
}

(Mocha.java)
public class Mocha extends CondimentDecorator {
    public Mocha(Beverage beverage) {
        super(beverage);
    }

    @Override
    public String getDescription() {
        return beverage.getDescription() + " + mocha";
    }

    public double cost() {
        return 0.20 + beverage.cost();
    }
}

(Test.java)
public class Test {
    public static void main(String[] args) {
        Beverage espresso = new Espresso();
        System.out.println(espresso.getDescription() + "$" + espresso.cost());

        Beverage decorator = new Milk(new Mocha(espresso));
        System.out.println(decorator.getDescription() + "$" + decorator.cost());
    }
}

输出:
Espresso$1.99
Espresso + mocha + milk$3.49

在java的I/O相关类中就可以看到装饰者模式的应用,但是也要防止过分使用,不然会造成大量的小类,变得复杂。

你可能感兴趣的:(设计模式,装饰器模式,设计模式)