诗曰:
法宝威力需增强,继承子类太繁琐。
装饰者模式来相助,动态添法显神通。
📖 故事
话说师徒四人来到"法力增强山",悟空觉得金箍棒威力不够,想要增强法力。
悟空愁道:"师父,这山的妖怪厉害,俺老孙的金箍棒威力不够啊!"
唐僧道:"悟空,你可有法子增强法力?"
悟空挠头:"徒儿倒是想过,要么打造一把新棒子,要么给金箍棒附魔。可要是每种附魔都要打造新棒子,那不得累死俺老孙!"
🐉 踩坑打怪:继承爆炸之劫
第一劫:类爆炸
悟空想了个笨办法:
java
// 基础金箍棒
public class GoldenCudgel {
public void attack() {
System.out.println("金箍棒 - 普通攻击!");
}
}
// 火焰金箍棒
public class FireGoldenCudgel extends GoldenCudgel {
@Override
public void attack() {
super.attack();
System.out.println("附加火焰伤害!");
}
}
// 冰冻金箍棒
public class IceGoldenCudgel extends GoldenCudgel {
@Override
public void attack() {
super.attack();
System.out.println("附加冰冻伤害!");
}
}
// 雷电金箍棒
public class ThunderGoldenCudgel extends GoldenCudgel {
@Override
public void attack() {
super.attack();
System.out.println("附加雷电伤害!");
}
}
// 火焰 + 冰冻金箍棒
public class FireIceGoldenCudgel extends GoldenCudgel {
@Override
public void attack() {
super.attack();
System.out.println("附加火焰伤害!");
System.out.println("附加冰冻伤害!");
}
}
// 火焰 + 雷电金箍棒...
// 冰冻 + 雷电金箍棒...
// 火焰 + 冰冻 + 雷电金箍棒...
八戒惊呼: "猴哥!你这得有几十种组合啊!每加一种附魔,就要多好几个类!"
悟空怒道: "正是!这'继承爆炸'太坑了!俺老孙得想个巧法子!"
⚔️ 装饰者模式大法
第一步:定义组件接口
java
// 武器接口
public interface Weapon {
void attack();
int getDamage();
}
第二步:实现具体组件
java
// 基础金箍棒
public class GoldenCudgel implements Weapon {
@Override
public void attack() {
System.out.println("金箍棒 - 普通攻击!");
}
@Override
public int getDamage() {
return 100;
}
}
第三步:实现装饰者基类
java
// 装饰者基类
public abstract class WeaponDecorator implements Weapon {
protected Weapon weapon; // 持有一个武器引用
public WeaponDecorator(Weapon weapon) {
this.weapon = weapon;
}
@Override
public void attack() {
weapon.attack(); // 委托给被装饰的武器
}
@Override
public int getDamage() {
return weapon.getDamage();
}
}
第四步:实现具体装饰者
java
// 火焰附魔装饰者
public class FireEnchantDecorator extends WeaponDecorator {
public FireEnchantDecorator(Weapon weapon) {
super(weapon);
}
@Override
public void attack() {
weapon.attack();
System.out.println("附加火焰伤害!🔥");
}
@Override
public int getDamage() {
return weapon.getDamage() + 20;
}
}
// 冰冻附魔装饰者
public class IceEnchantDecorator extends WeaponDecorator {
public IceEnchantDecorator(Weapon weapon) {
super(weapon);
}
@Override
public void attack() {
weapon.attack();
System.out.println("附加冰冻伤害!❄️");
}
@Override
public int getDamage() {
return weapon.getDamage() + 15;
}
}
// 雷电附魔装饰者
public class ThunderEnchantDecorator extends WeaponDecorator {
public ThunderEnchantDecorator(Weapon weapon) {
super(weapon);
}
@Override
public void attack() {
weapon.attack();
System.out.println("附加雷电伤害!⚡");
}
@Override
public int getDamage() {
return weapon.getDamage() + 25;
}
}
// 吸血附魔装饰者
public class LifestealDecorator extends WeaponDecorator {
public LifestealDecorator(Weapon weapon) {
super(weapon);
}
@Override
public void attack() {
weapon.attack();
System.out.println("附加吸血效果!🩸");
}
@Override
public int getDamage() {
return weapon.getDamage() + 10;
}
}
第五步:实战演练
java
public class Main {
public static void main(String[] args) {
// 基础金箍棒
Weapon cudgel = new GoldenCudgel();
System.out.println("=== 基础金箍棒 ===");
cudgel.attack();
System.out.println("伤害:" + cudgel.getDamage());
// 火焰金箍棒
System.out.println("\n=== 火焰金箍棒 ===");
Weapon fireCudgel = new FireEnchantDecorator(new GoldenCudgel());
fireCudgel.attack();
System.out.println("伤害:" + fireCudgel.getDamage());
// 火焰 + 冰冻金箍棒
System.out.println("\n=== 火焰 + 冰冻金箍棒 ===");
Weapon fireIceCudgel = new IceEnchantDecorator(
new FireEnchantDecorator(new GoldenCudgel())
);
fireIceCudgel.attack();
System.out.println("伤害:" + fireIceCudgel.getDamage());
// 火焰 + 冰冻 + 雷电金箍棒
System.out.println("\n=== 火焰 + 冰冻 + 雷电金箍棒 ===");
Weapon ultimateCudgel = new ThunderEnchantDecorator(
new IceEnchantDecorator(
new FireEnchantDecorator(new GoldenCudgel())
)
);
ultimateCudgel.attack();
System.out.println("伤害:" + ultimateCudgel.getDamage());
// 终极形态:全附魔 + 吸血
System.out.println("\n=== 终极形态:全附魔 + 吸血 ===");
Weapon godCudgel = new LifestealDecorator(
new ThunderEnchantDecorator(
new IceEnchantDecorator(
new FireEnchantDecorator(new GoldenCudgel())
)
)
);
godCudgel.attack();
System.out.println("伤害:" + godCudgel.getDamage());
}
}
输出:
=== 基础金箍棒 ===
金箍棒 - 普通攻击!
伤害:100
=== 火焰金箍棒 ===
金箍棒 - 普通攻击!
附加火焰伤害!🔥
伤害:120
=== 火焰 + 冰冻金箍棒 ===
金箍棒 - 普通攻击!
附加火焰伤害!🔥
附加冰冻伤害!❄️
伤害:135
=== 火焰 + 冰冻 + 雷电金箍棒 ===
金箍棒 - 普通攻击!
附加火焰伤害!🔥
附加冰冻伤害!❄️
附加雷电伤害!⚡
伤害:160
=== 终极形态:全附魔 + 吸血 ===
金箍棒 - 普通攻击!
附加火焰伤害!🔥
附加冰冻伤害!❄️
附加雷电伤害!⚡
附加吸血效果!🩸
伤害:170
🏆 战斗总结
悟空得意: "哈哈!俺老孙这装饰者模式,想加什么附魔就加什么,不用打造新棒子!"
八戒问: "猴哥,这和继承有啥区别?"
悟空答: "呆子,听好了------"
| 对比项 | 继承 | 装饰者模式 |
|---|---|---|
| 类数量 | 组合爆炸 | 线性增长 |
| 灵活性 | 编译时固定 | 运行时动态组合 |
| 扩展性 | 改代码 | 加新装饰者 |
| 职责 | 容易混杂 | 单一职责 |
本章要点
| 要点 | 说明 |
|---|---|
| 核心思想 | 动态地给对象添加职责,继承的替代方案 |
| 适用场景 | 需要动态添加功能、避免类爆炸 |
| 优点 | 灵活组合、符合开闭原则、单一职责 |
| 缺点 | 装饰者过多会增加复杂度、调试困难 |
下回预告
话说师徒继续西行,来到"真假美猴王岭"。两个悟空一模一样,如何辨别?且看代理模式如何设关卡!
欲知后事如何,且听第六回分解!