装饰者模式

装饰者模式

什么是装饰者模式

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

为什么使用装饰者模式

装饰模式是为已有功能动态地添加更多功能的一种方式

当系统需要新功能的时候,是向旧的类中添加新的代码。这些新加的代码通常装饰了原有类的核心职责或主要行为,在主类中加入了新的字段,新的方法和新的逻辑,从而增加了主类的复杂度

而装饰模式却提供了一个非常好的解决方案,它把每个要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象,因此,当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象了

有效地把类的核心职责和装饰功能区分开

示例

以下是一个使用Java实现的装饰者模式示例,以咖啡店中各种咖啡和其配料(装饰者)为例:

基础饮料类

// 抽象装饰者与被装饰者共享的接口
public abstract class Beverage {
    String description = "Unknown Beverage";

    public String getDescription() {
        return description;
    }

    public abstract double cost();
}

具体的饮料类(被装饰者)

public class Espresso extends Beverage {
    public Espresso() {
        description = "Espresso";
    }

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

接下来是装饰者的抽象类及具体的装饰者类:

装饰者抽象类

public abstract class CondimentDecorator extends Beverage {
    public abstract String getDescription();
}

具体的装饰者类 - 摩卡酱

public class Mocha extends CondimentDecorator {
    private Beverage beverage;

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

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

    @Override
    public double cost() {
        return .20 + beverage.cost();
    }
}

具体的装饰者类 - 奶泡

public class WhippedMilk extends CondimentDecorator {
    private Beverage beverage;

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

    @Override
    public String getDescription() {
        return beverage.getDescription() + ", Whipped Milk";
    }

    @Override
    public double cost() {
        return .50 + beverage.cost();
    }
}

最后,我们创建并装饰一个饮料实例:

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

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

        Beverage ultimateEspresso = new WhippedMilk(decoratedEspresso);
        System.out.println(ultimateEspresso.getDescription() + " $" + ultimateEspresso.cost());
    }
}

这个例子中,Espresso 是基础饮料,Mocha 和 WhippedMilk 是装饰者,它们可以在不修改原有Espresso类的基础上为其增加额外的功能(描述和价格)。

结果

Espresso $1.99
Espresso, Mocha $2.19
Espresso, Mocha, Whipped Milk $2.69
Disconnected from the target VM, address: '127.0.0.1:54379', transport: 'socket'

总结

  1. 定义抽象装饰者与被装饰者共享的接口(其实就是提供了规范)
  2. **具体的饮料类(被装饰者)**继承了共享接口拥有了规范中定义得能力
  3. 装饰者抽象类同样继承了共享接口拥有了规范中定义得能力
  4. 具体得装饰者其实就是将被装饰者增强了,把装饰者作为参数传递,对传递得装饰者根据重写得方法将被装饰者增强
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值