前言
装饰者模式是结构型设计模式的一种,装饰者模式可以在不修改原代码的基础上,动态的添加一些其他的功能,并且通过不同的装饰者实现功能的组合。
实现
什么是功能的组合呢?比如饮料店存在两种饮料,分别为咖啡和茶,它们都是饮料接口的实现类,我们买饮料之后,还可以添加一些小料,那么怎么动态的组合添加我们想要的小料呢?我们可以定义一个加小料抽象装饰者类,那么为了保证我们添加小料后的装饰者类还是饮料,让该抽象装饰类实现饮料类,并且引入饮料对象,便于子类调用具体饮料对象的方法。定义装饰类也就是具体小料装饰类继承抽象装饰类,重写方法,加入小料调用原方法即可。
代码实现
// 定义饮品接口
public interface Beverage {
String getDescription();
double cost();
}
// 实现牛奶类
public class Tea implements Beverage {
@Override
public String getDescription() {
return "Tea";
}
@Override
public double cost() {
return 0.50;
}
}
// 实现咖啡类
public class Coffee implements Beverage {
@Override
public String getDescription() {
return "Coffee";
}
@Override
public double cost() {
return 1.99;
}
}
//小料抽象类,实现饮料类,确保装饰类也是饮料类,方便实现组合
public abstract class CondimentDecoration implements Beverage {
//通过引入饮料对象,实现功能组合
Beverage beverage;
public CondimentDecoration(Beverage beverage) {
this.beverage = beverage;
}
public abstract String getDescription();
public abstract double cost();
}
//牛奶具体装饰类
public class MilkDecoration extends CondimentDecoration{
public MilkDecoration(Beverage beverage) {
super(beverage);
}
@Override
public String getDescription() {
return beverage.getDescription()+"加牛奶;";
}
@Override
public double cost() {
return beverage.cost()+0.2;
}
}
//糖具体装饰类
public class SugarDecoration extends CondimentDecoration{
public SugarDecoration(Beverage beverage) {
super(beverage);
}
@Override
public String getDescription() {
return beverage.getDescription()+"加糖;";
}
@Override
public double cost() {
return beverage.cost()+0.3;
}
}
//测试
public class Test {
public static void main(String[] args) {
//咖啡+牛奶+糖
Beverage coffee = new Coffee();
MilkDecoration MilkCoff = new MilkDecoration(coffee);
SugarDecoration sugarCoff = new SugarDecoration(MilkCoff);
System.out.println(sugarCoff.getDescription() + " " + sugarCoff.cost());
}
}
优缺点
优点: 1:符合开闭原则,通过组合的方式,在不修改原代码的条件下,动态的添加功能
2:防止类的爆炸式的递增,如果我们采用继承的方式实现功能的增强,那就需要更多的类,比如咖啡加牛奶类、咖啡加糖类、咖啡牛奶糖类等等,如果需要添加其他的小料,类将会爆炸性的递增
缺点:
1:装饰者模式通过引用的方式实现功能的增强,如果引用的类较多,可能导致引用的类之间的关系难以维护
2:进行装饰时可能涉及到多个装饰者的创建,会带来性能上的开销