设计模式——装饰器模式(Decorator Pattern)

文章通过一个生动的例子介绍了装饰器模式,它用于向现有对象添加新功能而不改变其结构。作者提供了一个Java代码示例,展示了如何使用装饰器模式来扩展扫地这个基本任务,添加拖地、喂猫和铲屎等家务。文章强调了装饰器模式的优势,如低耦合和可独立发展,同时也指出其可能的复杂性,特别是在需要自定义执行顺序时。
摘要由CSDN通过智能技术生成

很久没有写博客了,最近也有很多事情要处理,也在努力的备考软件考试,正好模拟题中有一道关于装饰器模式的题,觉得还不错,所以特地写一篇文章希望能分享给小伙伴们。

装饰器模式的作用:允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。

接下来继续举一个简单的例子:

曾经的我每天打扫卫生只要扫扫地就好了,但是最近养了一只小猫咪,家里的卫生就得更加注意了,不得不每天扫地,拖地,喂猫,铲屎,真的好忙啊!但是为了可爱的小猫咪,我干了!

 曾经:

现在:

 有小伙伴们好奇为什么扫地不是跟其他家务在一列中呢?因为扫地是最主要的家务,不管有没有小猫咪都会扫地,我希望在不改变我扫地的原逻辑下,新增其他家务,这时候就可以使用装饰器模式。

代码逻辑如下:

主逻辑扫地类:

/**
 * @description:扫地
 * @author: Me
 * @createDate: 2023/5/1 23:15
 * @version: 1.0
 */
public class SaoDi {

    public void doWork() {
        System.out.println("扫个地");
    }
}

装饰器控制类:

/**
 * @description:装饰器开关,用于控制所有装饰器类
 * @author: Me
 * @createDate: 2023/5/1 23:15
 * @version: 1.0
 */
public class Decorator extends SaoDi{
    private SaoDi work;
    // 构造器根据入参的类型,确定调用的方法,实际采用了多态的思想
    public Decorator(SaoDi work) {
        this.work = work;
    }
    public void doWork() {
        if (work != null) {
            // 根据传入家务的类型去调用做家务的方法
            work.doWork();
        }
    }
}

三种不同的装饰器家务类:

/**
 * @description:拖地
 * @author: Me
 * @createDate: 2023/5/1 23:19
 * @version: 1.0
 */
public class TuoDi extends Decorator{
    public TuoDi(SaoDi work) {
        super(work);
    }
    // 做家务的方法
    public void doWork() {
        // 调用构造器中参数对象的做家务方法
        super.doWork();
        System.out.println("拖个地");
    }
}
/**
 * @description:喂猫
 * @author: Me
 * @createDate: 2023/5/1 23:21
 * @version: 1.0
 */
public class WeiMao extends Decorator{
    public WeiMao(SaoDi work) {
        super(work);
    }
    // 做家务的方法
    public void doWork() {
        // 调用构造器中参数对象的做家务方法
        super.doWork();
        System.out.println("喂个猫");
    }
}
/**
 * @description:铲屎
 * @author: Me
 * @createDate: 2023/5/1 23:21
 * @version: 1.0
 */
public class ChanShi extends Decorator{
    public ChanShi(SaoDi work) {
        super(work);
    }
    // 做家务的方法
    public void doWork() {
        // 调用构造器中参数对象的做家务方法
        super.doWork();
        System.out.println("铲个屎");
    }
}

开始选择做哪些家务:

/**
 * @description:调用类
 * @author: Me
 * @createDate: 2023/5/1 23:22
 * @version: 1.0
 */
public class Test {
    public static void main(String[] args) {
        // 采用多重对象嵌套的逻辑来在扫地操作前后增加其他操作
        // 如果doWork方法中,super.doWork在自己的方法逻辑前,则先执行创建对象时的参数对象方法
        // 如果super.doWork方法在自己的方法逻辑之后,则先执行本对象方法,在寻找参数对象的方法
        SaoDi work = new TuoDi(new WeiMao(new SaoDi()));
        work.doWork();
    }
}

如上图调用逻辑,执行结果如下:

这种模式的优点在于:

1.装饰类和被装饰类可以独立发展,不会相互耦合。

2.各个装饰类的职责清晰明了,便于动态扩展,动态撤销。

缺点:

1.多层装饰比较复杂,装饰器如果需要按自定义顺序执行时比较困难,上述例子中我们可以发现,类创建过后被装饰类SaoDi与其他装饰类的执行顺序就已经被确定了,SaoDi只能在其他的装饰类之前执行,无法在装饰类之后执行,如果需要在装饰类之后执行SaoDi的方法,则只能修改装饰类,并且嵌套创建对象来定义执行顺序需要对于方法比较熟悉,不太容易上手。

其他的内容在菜鸟教程中有比较详细的过程我就不在此赘述了,这篇文章的意义就是希望能够通过自己的理解尽可能形象的解释一下设计模式,使得抽象的内容理解起来变得简单些。

菜鸟教程|装饰器模式

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值