Java装饰器模式实现详解
装饰器模式允许我们动态地给一个对象添加新的行为,而无需修改其原有类结构,下面通过咖啡店系统的案例来说明。

基础结构设计
// 1. 抽象组件 - 饮料接口
interface Beverage {
String getDescription();
double cost();
}
// 2. 具体组件 - 基础咖啡
class Espresso implements Beverage {
@Override
public String getDescription() {
return "浓缩咖啡";
}
@Override
public double cost() {
return 15.0;
}
}
class HouseBlend implements Beverage {
@Override
public String getDescription() {
return "综合咖啡";
}
@Override
public double cost() {
return 12.0;
}
}
class DarkRoast implements Beverage {
@Override
public String getDescription() {
return "深度烘焙咖啡";
}
@Override
public double cost() {
return 18.0;
}
}
装饰器基类
// 3. 抽象装饰器
abstract class CondimentDecorator implements Beverage {
protected Beverage beverage;
public CondimentDecorator(Beverage beverage) {
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription();
}
@Override
public double cost() {
return beverage.cost();
}
}
具体装饰器实现
// 4. 具体装饰器 - 配料
class Milk extends CondimentDecorator {
public Milk(Beverage beverage) {
super(beverage);
}
@Override
public String getDescription() {
return beverage.getDescription() + " + 牛奶";
}
@Override
public double cost() {
return beverage.cost() + 3.0;
}
}
class Mocha extends CondimentDecorator {
public Mocha(Beverage beverage) {
super(beverage);
}
@Override
public String getDescription() {
return beverage.getDescription() + " + 摩卡";
}
@Override
public double cost() {
return beverage.cost() + 5.0;
}
}
class Whip extends CondimentDecorator {
public Whip(Beverage beverage) {
super(beverage);
}
@Override
public String getDescription() {
return beverage.getDescription() + " + 奶油";
}
@Override
public double cost() {
return beverage.cost() + 4.0;
}
}
class Soy extends CondimentDecorator {
public Soy(Beverage beverage) {
super(beverage);
}
@Override
public String getDescription() {
return beverage.getDescription() + " + 豆浆";
}
@Override
public double cost() {
return beverage.cost() + 2.0;
}
}
客户端使用示例
public class CoffeeShop {
public static void main(String[] args) {
// 基础咖啡
Beverage espresso = new Espresso();
System.out.println(espresso.getDescription() + " 价格: ¥" + espresso.cost());
// 添加配料
Beverage latte = new Milk(espresso);
System.out.println(latte.getDescription() + " 价格: ¥" + latte.cost());
// 多层装饰
Beverage mochaLatte = new Mocha(latte);
System.out.println(mochaLatte.getDescription() + " 价格: ¥" + mochaLatte.cost());
// 复杂组合
Beverage custom = new Whip(new Mocha(new Soy(new DarkRoast())));
System.out.println(custom.getDescription() + " 价格: ¥" + custom.cost());
// 动态添加额外配料
Beverage doubleMochaLatte = new Mocha(new Mocha(new Milk(new HouseBlend())));
System.out.println(doubleMochaLatte.getDescription() + " 价格: ¥" + doubleMochaLatte.cost());
}
}
输出结果
浓缩咖啡 价格: ¥15.0
浓缩咖啡 + 牛奶 价格: ¥18.0
浓缩咖啡 + 牛奶 + 摩卡 价格: ¥23.0
深度烘焙咖啡 + 豆浆 + 摩卡 + 奶油 价格: ¥29.0
综合咖啡 + 牛奶 + 摩卡 + 摩卡 价格: ¥25.0
改进版本 - 使用泛型
// 更通用的装饰器实现
abstract class AbstractDecorator<T extends Beverage> implements Beverage {
protected T component;
public AbstractDecorator(T component) {
this.component = component;
}
@Override
public String getDescription() {
return component.getDescription();
}
@Override
public double cost() {
return component.cost();
}
}
// 使用泛型的具体装饰器
class Sugar<T extends Beverage> extends AbstractDecorator<T> {
public Sugar(T component) {
super(component);
}
@Override
public String getDescription() {
return super.getDescription() + " + 糖";
}
@Override
public double cost() {
return super.cost() + 1.0;
}
}
装饰器模式的优势
- 开闭原则:无需修改现有类即可扩展功能
- 灵活性:可以在运行时动态组合不同的行为
- 避免类膨胀:避免了创建大量子类
- 细粒度控制:可以精确控制添加的功能
实际应用场景
- Java I/O流:
BufferedReader装饰FileReader - GUI组件:添加滚动条、边框等功能
- 日志系统:添加时间戳、格式化等功能
- 权限控制:动态添加访问控制功能
这个案例展示了装饰器模式的核心思想:通过组合而不是继承来扩展对象的功能,既保持了类的单一职责,又提供了极大的灵活性。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播