设计模式是一种基于经验的设计方法,可以帮助开发人员提高代码的重用度、灵活性和可维护性。其中,装饰模式是一种常见的设计模式,它可以在运行时动态地扩展对象的功能而不必修改代码,既能够遵循开放封闭原则,也能够实现松耦合的设计。
装饰模式的定义
装饰模式(Decorator Pattern)是一种结构型设计模式,它允许向一个现有的对象添加新的功能,同时又不改变其结构。装饰模式的核心思想是“包装对象”,即用一个装饰类来包装真实的对象,从而动态地增加对象的功能。这种方式可以在不修改原有代码的情况下,组合不同的装饰器实现不同的功能组合。
装饰模式的组成部分
装饰模式包含以下几个角色:
1. 抽象组件(Component):定义一个对象接口,可以给这些对象动态地添加职责。
2. 具体组件(ConcreteComponent):定义了一个具体的对象,也可以给这个对象添加一些职责。
3. 抽象装饰器(Decorator):装饰抽象组件的基类,同时它也通过继承实现了与抽象组件相同的接口。
4. 具体装饰器(ConcreteDecorator):继承自抽象装饰器,实现具体的装饰功能。
装饰模式的优点
1. 灵活性好:装饰模式可以动态地增加和删除对象的职责,在不影响原有代码的情况下,实现新的功能组合。
2. 可扩展性好:由于装饰器和组件的接口是相同的,所以可以无限扩展功能,而且可以按需要进行组合。
3. 不破坏原有代码:通过包装一个对象,不必修改原有代码即可实现功能的增强,符合开放封闭原则。
装饰模式的应用场景
1. 动态地给一个对象添加新的功能,而且还能够动态地撤销这些功能。
2. 需要增加一些额外的功能,但是又不想修改原有的代码。
3. 用继承来扩展功能不利于系统的扩展和维护。
装饰模式的实例
现在我们来看一个实际的例子,如何使用装饰模式来实现对象的功能扩展。
我们有一个饮料类(Beverage),它有一个基本的描述方法(getDescription)和一个计算价格的方法(cost)。现在我们要在这个饮料类上添加一些调料(Condiment),比如牛奶、摩卡、豆浆等,这些调料也有自己的价格和描述。我们需要用装饰模式实现这些调料的扩展。
首先,我们定义一个抽象饮料类(Beverage):
```
public abstract class Beverage {
String description = "Unknown Beverage";
public String getDescription() {
return description;
}
public abstract double cost();
}
```
然后,我们定义一个具体的饮料类(HouseBlend):
```
public class HouseBlend extends Beverage {
public HouseBlend() {
description = "House Blend Coffee";
}
public double cost() {
return .89;
}
}
```
接着,我们定义一个抽象装饰器类(CondimentDecorator),来包装具体的饮料类:
```
public abstract class CondimentDecorator extends Beverage {
public abstract String getDescription();
}
```
然后,我们定义具体的装饰器类,比如牛奶(Milk):
```
public class Milk extends CondimentDecorator {
Beverage beverage;
public Milk(Beverage beverage) {
this.beverage = beverage;
}
public String getDescription() {
return beverage.getDescription() + ", Milk";
}
public double cost() {
return .10 + beverage.cost();
}
}
```
最后,我们就可以按照需要来进行调料的组合了:
```
Beverage beverage = new HouseBlend(); // 一杯 House Blend 咖啡
beverage = new Milk(beverage); // 加入牛奶
```
这样,我们就实现了装饰模式来进行饮料类的扩展。
扫码咨询 领取资料