本文目录导读:

我将为您提供一个完整的Java装饰者模式案例,以咖啡店点餐系统为例来演示。
基本结构
// 1. 抽象组件(Component)- 饮料接口
public interface Beverage {
String getDescription();
double cost();
}
// 2. 具体组件(ConcreteComponent)- 具体的饮料
public class Espresso implements Beverage {
@Override
public String getDescription() {
return "浓缩咖啡";
}
@Override
public double cost() {
return 15.0;
}
}
public class HouseBlend implements Beverage {
@Override
public String getDescription() {
return "综合咖啡";
}
@Override
public double cost() {
return 12.0;
}
}
public class Decaf implements Beverage {
@Override
public String getDescription() {
return "低因咖啡";
}
@Override
public double cost() {
return 13.0;
}
}
// 3. 抽象装饰者(Decorator)- 调料装饰器
public abstract class CondimentDecorator implements Beverage {
protected Beverage beverage;
public CondimentDecorator(Beverage beverage) {
this.beverage = beverage;
}
@Override
public abstract String getDescription();
}
// 4. 具体装饰者(ConcreteDecorator)- 各种调料
public 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;
}
}
public 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;
}
}
public 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;
}
}
public class Soy extends CondimentDecorator {
public Soy(Beverage beverage) {
super(beverage);
}
@Override
public String getDescription() {
return beverage.getDescription() + ", 加豆浆";
}
@Override
public double cost() {
return beverage.cost() + 4.5;
}
}
客户端测试代码
public class CoffeeShop {
public static void main(String[] args) {
System.out.println("=== 咖啡店点餐系统 ===\n");
// 1. 点一杯纯浓缩咖啡
Beverage espresso = new Espresso();
System.out.println("订单1: " + espresso.getDescription());
System.out.println("价格: $" + espresso.cost() + "\n");
// 2. 点一杯综合咖啡,加双份摩卡和牛奶
Beverage houseBlend = new HouseBlend();
houseBlend = new Mocha(houseBlend);
houseBlend = new Mocha(houseBlend); // 双份摩卡
houseBlend = new Milk(houseBlend);
System.out.println("订单2: " + houseBlend.getDescription());
System.out.println("价格: $" + houseBlend.cost() + "\n");
// 3. 点一杯低因咖啡,加豆浆和奶泡
Beverage decaf = new Decaf();
decaf = new Soy(decaf);
decaf = new Whip(decaf);
System.out.println("订单3: " + decaf.getDescription());
System.out.println("价格: $" + decaf.cost() + "\n");
// 4. 一份豪华套餐:浓缩咖啡加所有调料
Beverage deluxe = new Espresso();
deluxe = new Milk(deluxe);
deluxe = new Mocha(deluxe);
deluxe = new Whip(deluxe);
deluxe = new Soy(deluxe);
System.out.println("订单4: " + deluxe.getDescription());
System.out.println("价格: $" + deluxe.cost());
}
}
运行结果
=== 咖啡店点餐系统 ===
订单1: 浓缩咖啡
价格: $15.0
订单2: 综合咖啡, 加摩卡, 加摩卡, 加牛奶
价格: $25.0
订单3: 低因咖啡, 加豆浆, 加奶泡
价格: $21.5
订单4: 浓缩咖啡, 加牛奶, 加摩卡, 加奶泡, 加豆浆
价格: $31.5
进阶版:带容量大小的咖啡
// 增加容量选项
public enum Size {
TALL, // 小杯
GRANDE, // 中杯
VENTI // 大杯
}
// 修改抽象组件接口
public interface Beverage {
String getDescription();
double cost();
Size getSize();
void setSize(Size size);
}
// 重写具体组件
public class Espresso implements Beverage {
private Size size = Size.GRANDE;
@Override
public String getDescription() {
return "浓缩咖啡";
}
@Override
public double cost() {
// 根据容量计算价格
switch(size) {
case TALL: return 15.0;
case GRANDE: return 18.0;
case VENTI: return 21.0;
default: return 15.0;
}
}
@Override
public Size getSize() {
return size;
}
@Override
public void setSize(Size size) {
this.size = size;
}
}
// 重写装饰者,根据容量计算调料价格
public abstract class CondimentDecorator implements Beverage {
protected Beverage beverage;
public CondimentDecorator(Beverage beverage) {
this.beverage = beverage;
}
@Override
public Size getSize() {
return beverage.getSize();
}
@Override
public void setSize(Size size) {
beverage.setSize(size);
}
}
public class Mocha extends CondimentDecorator {
public Mocha(Beverage beverage) {
super(beverage);
}
@Override
public String getDescription() {
return beverage.getDescription() + ", 加摩卡";
}
@Override
public double cost() {
// 摩卡根据不同容量加价
double mochaCost = 5.0;
if (getSize() == Size.TALL) {
mochaCost = 4.0;
} else if (getSize() == Size.VENTI) {
mochaCost = 6.0;
}
return beverage.cost() + mochaCost;
}
}
装饰者模式的优势
优点:
- 组合优于继承:动态地添加职责,比继承更灵活
- 开闭原则:可以在不修改原有代码的情况下添加新功能
- 可选组合:可以自由组合,产生丰富的效果
缺点:
- 增加复杂度:会产生很多小类,增加理解难度
- 调试困难:多层包装使调试变得复杂
- 顺序依赖:某些场景下装饰顺序可能影响最终结果
适用场景
- 需要动态、透明地给单个对象添加职责
- 需要扩展一个类的功能,或给一个类增加附加责任
- 需要动态撤销或恢复对象的某些功能
这个案例完整展示了Java装饰者模式的核心概念:通过包装对象来动态添加功能,而不是通过继承来静态地增加功能。
版权声明: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直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播