装饰者模式

30 阅读2分钟

前言

装饰者模式是结构型设计模式的一种,装饰者模式可以在不修改原代码的基础上,动态的添加一些其他的功能,并且通过不同的装饰者实现功能的组合。

实现

什么是功能的组合呢?比如饮料店存在两种饮料,分别为咖啡和茶,它们都是饮料接口的实现类,我们买饮料之后,还可以添加一些小料,那么怎么动态的组合添加我们想要的小料呢?我们可以定义一个加小料抽象装饰者类,那么为了保证我们添加小料后的装饰者类还是饮料,让该抽象装饰类实现饮料类,并且引入饮料对象,便于子类调用具体饮料对象的方法。定义装饰类也就是具体小料装饰类继承抽象装饰类,重写方法,加入小料调用原方法即可。

代码实现

// 定义饮品接口
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:进行装饰时可能涉及到多个装饰者的创建,会带来性能上的开销