1. 什么是装饰者模式?
装饰者模式,顾名思义,就是在不改变原有对象的情况下,新增功能或改变现有的行为,使得功能更加丰富和灵活。这种模式属于结构型模式,它是作为现有类的一个包装,而不需要修改原始类的结构而实现的,在软件开发中得到了广泛的应用。
2. 装饰者模式的结构
装饰者模式一般由四个角色组成:抽象组件、具体组件、装饰器和具体装饰器。
2.1 抽象组件:是一个抽象类或接口,定义一个对象必须实现的方法,它是一个基本的对象类型,可以被装饰。
2.2 具体组件:是继承或实现抽象组件的一个具体类,实现了组件的定义。
2.3 装饰器:是一个抽象类或接口,通过组合抽象组件的实例,来增加新的方法或属性,同时保证了其被装饰者的属性不变。
2.4 具体装饰器:是实现装饰器接口或继承装饰器抽象类的具体类,实现新的方法或属性,并可以调用被装饰对象的方法。
3. 装饰者模式的实现
我们用一个简单的例子来实现装饰者模式:
有一家奶茶店,它提供基本奶茶、小费奶茶和布丁奶茶,如果顾客还想要加冰或者加糖,店员可以给奶茶加装饰器来实现,具体实现代码如下:
首先定义奶茶抽象组件:
```
public interface MilkTea {
String getDescription();
double getPrice();
}
```
然后定义具体奶茶组件:
```
public class BasicMilkTea implements MilkTea {
@Override
public String getDescription() {
return "基本奶茶";
}
@Override
public double getPrice() {
return 10.0;
}
}
```
定义装饰器抽象类,并继承奶茶接口:
```
public abstract class MilkTeaDecorator implements MilkTea {
protected MilkTea milkTea;
public MilkTeaDecorator(MilkTea milkTea) {
this.milkTea = milkTea;
}
public String getDescription() {
return milkTea.getDescription();
}
public double getPrice() {
return milkTea.getPrice();
}
}
```
具体装饰器小费奶茶和布丁奶茶分别应用装饰器抽象类:
```
public class TipMilkTeaDecorator extends MilkTeaDecorator {
public TipMilkTeaDecorator(MilkTea milkTea) {
super(milkTea);
}
public String getDescription() {
return milkTea.getDescription() + " + 小费";
}
public double getPrice() {
return milkTea.getPrice() + 1.0;
}
}
public class PuddingMilkTeaDecorator extends MilkTeaDecorator {
public PuddingMilkTeaDecorator(MilkTea milkTea) {
super(milkTea);
}
public String getDescription() {
return milkTea.getDescription() + " + 布丁";
}
public double getPrice() {
return milkTea.getPrice() + 2.0;
}
}
```
客户端代码如下:
```
public class Client {
public static void main(String[] args) {
MilkTea basicMilkTea = new BasicMilkTea();
basicMilkTea = new TipMilkTeaDecorator(basicMilkTea);
basicMilkTea = new PuddingMilkTeaDecorator(basicMilkTea);
System.out.println(basicMilkTea.getDescription() + ",价格:" + basicMilkTea.getPrice());
}
}
```
输出结果为:基本奶茶 + 小费 + 布丁,价格:13.0。
4. 总结
通过本文的介绍,我们可以知道装饰者模式可以在不修改原始类的情况下,通过新增功能或改变现有的行为,使得功能更加丰富和灵活。在实际开发中,我们可以将需要装饰的对象作为构造器参数传递到装饰器中,以便于装饰器具有代理原始对象和添加功能的能力。同时,我们要注意避免装饰器层级过深或过多导致复杂度上升的情况。
扫码咨询 领取资料