装饰器模式定义
从代码层面而言,是对类的一个扩展或者是修饰,从传统方法而言,我们可以使用继承来对某一个类进行扩展,但是往往会导致会出现非常多的子类,如果我们要想避免这种情况,那么我们就可以使用设计模式中的——装饰器模式。
装饰器模式也称为包装模式是指在不改变现有对象结构的情况下,动态地给该对象增加一些职责,即增加其额外功能,提供了比继承更有弹性的替代方案(扩展原有对象的功能),属于结构型模式。装饰器模式的核心是功能扩展,使用装饰器模式可以透明且动态地扩展类的功能。简单来说,就是一个东西,然后不断在该东西上添加符合该物件的功能,进行扩展的模式
装饰器模式包含以下角色:
装饰器模式优缺点:
优点:
缺点:
使用场景
以下举一个装饰器模式的例子:
比如平时我们都肯定喝过奶茶,奶茶肯定有很多种,而且点的奶茶,还可以加料,比如加珍珠,加椰果之类的。这就可以用装饰器模式处理了。
创建Component对象,规定为MilkTea,行为功能为输出名字和输出价格:
public abstract class MilkTea {
protected abstract String getName();
protected abstract int getPrice();
}
创建ConcreteComponent,规定为焦糖奶茶:
public class CaramelMilkTea extends MilkTea {
@Override
protected String getName() {
return "焦糖奶茶";
}
@Override
protected int getPrice() {
return 20;
}
}
创建Decorator对象,进行静态代理
public abstract class Add extends MilkTea {
private final MilkTea milkTea;
public Add(MilkTea milkTea) {
this.milkTea = milkTea;
}
@Override
protected String getName() {
return this.milkTea.getName();
}
@Override
protected int getPrice() {
return this.milkTea.getPrice();
}
}
创建多个ConcreteDecorator对象,实现功能扩展(加装饰球、加缎带)
public class Pearl extends Add {
public Pearl(MilkTea milkTea) {
super(milkTea);
}
@Override
protected String getName() {
return super.getName() + ",加了珍珠";
}
@Override
protected int getPrice() {
return super.getPrice() + 5;
}
}
public class Coconut extends Add {
public Coconut(MilkTea milkTea) {
super(milkTea);
}
@Override
protected String getName() {
return super.getName() + ",加了椰果";
}
@Override
protected int getPrice() {
return super.getPrice() + 3;
}
}
测试类:
public class test {
public static void main(String[] args) {
System.out.println("点一杯焦糖奶茶");
MilkTea caramelMilkTea = new CaramelMilkTea();
System.out.println(caramelMilkTea.getName() + ",总价格:" + caramelMilkTea.getPrice() + "元");
System.out.println("加珍珠");
caramelMilkTea = new Pearl(caramelMilkTea);
System.out.println(caramelMilkTea.getName() + ",总价格:" + caramelMilkTea.getPrice() + "元");
System.out.println("再加椰果");
caramelMilkTea = new Coconut(caramelMilkTea);
System.out.println(caramelMilkTea.getName() + ",总价格:" + caramelMilkTea.getPrice() + "元");
}
}
输出结果如下所示:
点一杯焦糖奶茶
焦糖奶茶,总价格:20元
加珍珠
焦糖奶茶,加了珍珠,总价格:25元
再加椰果
焦糖奶茶,加了珍珠,加了椰果,总价格:28元
从结果可以看成功根据需求,获取到了一杯焦糖奶茶加了珍珠和椰果,并计算出价格。
总而言之:
在实际项目中,装饰器模式的运用可以通过遵循一些设计原则和最佳实践来更好地实现。首先,我们应该保持设计简单,避免过度使用装饰器,以及遵循面向对象的基本设计原则。其次,我们应该尽可能地避免重复代码和保持代码的可读性和可维护性。最后,我们应该考虑设计模式的上下文和这些模式的适用性,以及不同场景下应用不同设计模式的灵活性。
装饰器模式满足了设计原则的单一职责原则,可以在自己的装饰类中完成一些额外的功能逻辑拓展,而且不会影响到被装饰的主类,同时可以按需在运行时添加或删除这部分逻辑。
装饰器模式的重点是对抽象类接口方式的使用,同时被实现的接口可以通过构造函数传递其类,由此增加扩展性,并重写方法中可以通过父类实现的功能。
以上代码下载请点击该链接:https://github.com/Yarrow052/Java-package.git
更多【jvm-设计模式详解(十)——装饰器模式】相关视频教程:www.yxfzedu.com