装饰器模式来啦

装饰器模式是继承的替代模式,本质上也是通过对象抽象和对象组合的形式完成。装饰器模式也很少用在设计初始阶段,一般在重构或代码扩展阶段。当需要对现有的对象的行为进行增强时使用。

一、装饰器模式

装饰器模式和组合模式放在一起看是有一些相似的,区别在组合模式是对对象的组合且使用阶段是设计阶段,而装饰模式是对对象行为的组合且使用阶段是代码重构或扩展阶段(增强)

二、案例

举个🌰

看过金庸小说的读者都知道,在小说中有一种老江湖都惯用的武器------暗器,暗器顾名思义就是暗中的武器。类似霹雳子、霹雳雷火弹,蔟藜火弹,霹雳毒火弹等等

其中爆炸式暗器都是在霹雳子的基础上演化而来,进一步增大暗器的杀伤力或杀伤范围

咱可以用代码来构思各种霹雳子的演化和组合

首先对霹雳子进行抽象得到爆炸物,可定义该角色为抽象组件

java 复制代码
public interface BoomThing {

    // 获取爆炸物名称
    String getName();

    // 爆炸物杀伤力强度
    int getStrength();

}

霹雳子实现该抽象组件,可定义该角色为具体组件

java 复制代码
public class PiLiZi implements BoomThing{


    @Override
    public String getName() {
        return "霹雳子";
    }

    @Override
    public int getStrength() {
        return 10;
    }
}

上述代码为软件设计中的通用设计(多态),那么当前上述代码已经存在的前提下,如何对具体组件(霹雳子)的能力进行增强呢?

一般情况下可使用继承,但是继承会导致子类的泛滥,所以我们选择装饰器模式。

装饰器模式是继承的替代模式,装饰器模式也很少用在设计初始阶段,一般在重构或代码扩展阶段。当需要对现有的对象的行为进行增强时使用

接下来对霹雳子的行为进行增强,先对霹雳子加一个铁片增加杀伤力

定义抽象装饰器,对装饰器(增强物)抽象

java 复制代码
public abstract class AbstractAddStrengthDecorator implements BoomThing{

    protected BoomThing boomThing;

    public AbstractAddStrengthDecorator(BoomThing boomThing){
        this.boomThing = boomThing;
    }

    @Override
    public String getName() {
        return boomThing.getName();
    }

    @Override
    public int getStrength() {
        return boomThing.getStrength();
    }
}

使用铁片增强威力,该角色可为具体装饰器

java 复制代码
public class IronSheets extends AbstractAddStrengthDecorator{


    public IronSheets(BoomThing boomThing) {
        super(boomThing);
    }

    @Override
    public String getName() {
        return super.getName() + "加铁片";
    }

    @Override
    public int getStrength() {
        return super.getStrength() + 20;
    }
}

使用毒气增强威力,该角色可为具体装饰器

java 复制代码
public class PoisonGas extends AbstractAddStrengthDecorator{


    public PoisonGas(BoomThing boomThing) {
        super(boomThing);
    }

    @Override
    public String getName() {
        return super.getName() + "加毒气";
    }

    @Override
    public int getStrength() {
        return super.getStrength() + 100;
    }
}

客户端调用

java 复制代码
public class TestMain {
    public static void main(String[] args) {
        //单个组合装饰
        IronSheets ironSheets = new IronSheets(new PiLiZi());
        System.out.println("暗器名称:" + ironSheets.getName() + ",暗器强度:" + ironSheets.getStrength());
        
        //多个组合装饰(解决继承子类泛滥问题)
        PoisonGas poisonGas = new PoisonGas(new IronSheets(new PiLiZi()));
        System.out.println("暗器名称:" + poisonGas.getName() + ",暗器强度:" + poisonGas.getStrength());
    }
}

三、总结

装饰器模式通过嵌套包装多个装饰器对象,可以实现多层次的功能增强。每个具体装饰器类都可以选择性地增加新的功能,同时保持对象接口的一致性

相关推荐
捕鲸叉2 天前
C++设计模式之适配器模式与桥接模式,装饰器模式及代理模式相似点与不同点
设计模式·桥接模式·适配器模式·装饰器模式
Miqiuha6 天前
装饰器设计模式学习
java·学习·装饰器模式
南城花随雪。8 天前
Spring框架之装饰者模式 (Decorator Pattern)
java·开发语言·装饰器模式
编程、小哥哥8 天前
设计模式之装饰器模式(SSO单点登录功能扩展,增加拦截用户访问方法范围场景)
java·设计模式·装饰器模式
吾与谁归in8 天前
【C#设计模式(10)——装饰器模式(Decorator Pattern)】
设计模式·c#·装饰器模式
编码熊(Coding-Bear)18 天前
设计模式之结构型模式---装饰器模式
android·java·设计模式·装饰器模式
G皮T19 天前
【设计模式】结构型模式(一):适配器模式、装饰器模式
java·设计模式·适配器模式·装饰器模式·decorator·adapter·结构型模式
无敌岩雀20 天前
C++设计模式结构型模式———装饰模式
c++·设计模式·装饰器模式
小白23 天前
C# 结构型设计模式----装饰器模式
设计模式·装饰器模式
程序猿阿伟24 天前
《C++中的魔法:实现类似 Python 的装饰器模式》
java·c++·装饰器模式