8、设计模式之装饰模式

开始之前

本章节是一个系列,里面用的的代码实例都是连贯的。在实现某一种设计模式时,为了减少代码篇幅,前面博客出现model类(仅限公用的model类,比如compute、CPU、Mem、Disk等纯对象类)不会重复出现,读者在阅读某一篇博客时,如果发现突然出现了一个新的model类,在本片博客中没有其定义,可以往前面的博客翻一下!

最后,当本系列更新完成后,我会整个的代码完整贴出来,提供下载链接!

装饰器模式

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

装饰器模式通过将对象包装在装饰器类中,以便动态地修改其行为。

这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

介绍

意图: 动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。

主要解决: 一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀。

何时使用: 在不想增加很多子类的情况下扩展类。

如何解决: 将具体功能职责划分,同时继承装饰者模式。

关键代码:

  1. Component 类充当抽象角色,不应该具体实现。

  2. 修饰类引用和继承 Component 类,具体扩展类重写父类方法。

优点: 装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。

缺点: 多层装饰比较复杂。

使用场景:

  1. 扩展一个类的功能。
  2. 动态增加功能,动态撤销。

注意事项: 可代替继承。

装饰器模式包含以下几个核心角色:

  • 抽象组件(Component): 定义了原始对象和装饰器对象的公共接口或抽象类,可以是具体组件类的父类或接口。
  • 具体组件(Concrete Component): 是被装饰的原始对象,它定义了需要添加新功能的对象。
  • 抽象装饰器(Decorator): 继承自抽象组件,它包含了一个抽象组件对象,并定义了与抽象组件相同的接口,同时可以通过组合方式持有其他装饰器对象。
  • 具体装饰器(Concrete Decorator): 实现了抽象装饰器的接口,负责向抽象组件添加新的功能。具体装饰器通常会在调用原始对象的方法之前或之后执行自己的操作。

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

代码实现

以电话为例子,首先定义接口类、和早期的座机

public interface Phone {

    void call();
} 
//telephone 只有打电话的功能
public class TelePhone implements Phone{

    public void call() {
        System.out.println("TelePhone call····");
    }
}

后续出现了移动电话可以发送短信

public class MobilePhone implements Phone{
    protected Phone phone;
    public MobilePhone(Phone phone){
        this.phone = phone;
    }
    public void sendMessage(){
        System.out.println("MobilePhone send message");
    }

    @Override
    public void call() {
        sendMessage();
        phone.call();
    }
}

后面又出现了照相功能

public class PhotoPhone extends MobilePhone{
    public PhotoPhone(Phone phone) {
        super(phone);
    }

    public void photo() {
        System.out.println("PhotoPhone photo");
    }

    public void call(){
        photo();
        phone.call();
    }
}

这样的业务层就可以更具业务条件判断一些功能的添加和删除

public class Client {
    public static void main(String[] args) {
        Phone phone = new TelePhone();//只有打电话功能
        //通过装饰模式加条件判断,可以实现动态的添加、删除功能
        if (addMobile()){//通过 MobilePhone 装饰 Phone 提供send message功能
            phone = new MobilePhone(phone);
        }
        if (addPhoto()){ //通过PhotoPhone 装饰 Phone 提供photo功能
            phone = new PhotoPhone(phone);
        }
        phone.call();
    }

    private static boolean addMobile(){
        return true;
    }

    private static boolean addPhoto(){
        return true;
    }
}

  • 29
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风吹千里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值