Java 设计模式西游篇 - 第五回:装饰者模式添法力 悟空披挂新战袍

诗曰:

复制代码
法宝威力需增强,继承子类太繁琐。
装饰者模式来相助,动态添法显神通。

📖 故事

话说师徒四人来到"法力增强山",悟空觉得金箍棒威力不够,想要增强法力。

悟空愁道:"师父,这山的妖怪厉害,俺老孙的金箍棒威力不够啊!"

唐僧道:"悟空,你可有法子增强法力?"

悟空挠头:"徒儿倒是想过,要么打造一把新棒子,要么给金箍棒附魔。可要是每种附魔都要打造新棒子,那不得累死俺老孙!"

🐉 踩坑打怪:继承爆炸之劫

第一劫:类爆炸

悟空想了个笨办法:

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

🏆 战斗总结

悟空得意: "哈哈!俺老孙这装饰者模式,想加什么附魔就加什么,不用打造新棒子!"

八戒问: "猴哥,这和继承有啥区别?"

悟空答: "呆子,听好了------"

对比项 继承 装饰者模式
类数量 组合爆炸 线性增长
灵活性 编译时固定 运行时动态组合
扩展性 改代码 加新装饰者
职责 容易混杂 单一职责

本章要点

要点 说明
核心思想 动态地给对象添加职责,继承的替代方案
适用场景 需要动态添加功能、避免类爆炸
优点 灵活组合、符合开闭原则、单一职责
缺点 装饰者过多会增加复杂度、调试困难

下回预告

话说师徒继续西行,来到"真假美猴王岭"。两个悟空一模一样,如何辨别?且看代理模式如何设关卡!

欲知后事如何,且听第六回分解!


相关推荐
香香甜甜的辣椒炒肉9 小时前
Spring(1)基本概念+开发的基本步骤
java·后端·spring
成都渲染101云渲染666610 小时前
跳出“硬件堆砌”陷阱|渲染101如何用技术重构云渲染的专业价值?
java·前端·javascript
golang学习记10 小时前
IDEA 2026.1全新调试新特性:Spring Boot调试不再靠猜!
java·spring boot·intellij-idea
橘子编程10 小时前
OpenClaw(小龙虾)完整知识汇总
java·前端·spring boot·spring·spring cloud·html5
大阿明10 小时前
SpringBoot - Cookie & Session 用户登录及登录状态保持功能实现
java·spring boot·后端
Binary-Jeff10 小时前
Spring 创建 Bean 的关键流程
java·开发语言·前端·spring boot·后端·spring·学习方法
rOuN STAT10 小时前
MySQL:基础操作(增删查改)
java
→长歌10 小时前
2026Java面试30题精解
java·python·面试
SHoM SSER10 小时前
Spring Boot性能提升的核武器,速度提升500%!
java·spring boot·后端
weixin_4250230011 小时前
Spring Boot 2.7 + JDK8 集成 Knife4j 4.1.0 教程(仅展示带注解接口)
java·spring boot·后端