【设计模式】29.结构型模式-装饰模式(Decorator)

一、描述

装饰模式能够在不改变原来对象结构和功能的前提下,动态的给对象增加新的功能,相比于使用子类扩展的方式,装饰模式更加的灵活。

角色

(1)抽象构件类:为具体构件类和装饰类提供抽象方法。
(2)具体构建类:是抽象构建类的子类,实现抽象方法,用于定义具体的构件对象。
(3)抽象装饰类:是抽象构件类的子类,维护了一个指向抽象构件类的引用,同时提供构造方法或者set方法设置具体构件类。提供了设置装饰的抽象方法。
(4)具体装饰类:是抽象装饰类的子类,实现了其装饰的抽象方法。负责向构建中添加新的职责,每一个具体装饰类都定义了一些新的行为,可以调用抽象装饰类中定义的方法,并可以增加新的职责用以扩充对象的行为。

类图

在这里插入图片描述

二、优点

(1)装饰者模式和继承关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性
(2)通过使用不同的具体装饰者类及他们不同的组合顺序,可以得到不同装饰后具有不同行为或者状态的对象
(3)符合开闭原则(对扩展开放,对修改关闭)
(4)动态扩展类功能,比类继承灵活,且对客户端透明
(5)继承关系的一种替代方案,相比于类继承的父子关系,装饰模式更像是一种组合关系(is-a)
(6)可以对同一个被装饰对象进行多次装饰,创建出不同行为的符合功能

三、缺点

(1)多层装饰比较复杂
(2)装饰嵌套过多,会产生过多小对象(每个装饰层都创建一个相应的对象)
(3)装饰嵌套过多,易于出错,且调试排查比较麻烦(需要一层一层对装饰器进行排查,以确定是哪一个装饰层出错)

四、使用场景

(1)需要扩展一个类的功能,或给一个类增加附加功能
(2)需要动态地给一个对象增加功能,且这些功能可以再动态的撤销
(3)需要为一批兄弟类进行改装或加装功能

五、示例

以手机为例,从刚开始的基础版手机只具备打电话、发短信的功能,到后来可以安装QQ、浏览网页的功能,再到现在的智能手机可以安装各种各样的app,堪比一个小型电脑。手机的发展可以看做一个装饰者模式,以打电话、发短信为最基本的功能,QQ、浏览器、微信、王者荣耀等可以动态添加到手机的功能中。

类图

在这里插入图片描述

代码

(1)手机

public abstract class MobilePhone {
    /**
     * 抽象操作方法
     */
    abstract void operation();
}

(2)基础功能手机

public class FirstGenerationPhone extends MobilePhone {
    @Override
    void operation() {
        call();
        sms();
    }

    private void call() {
        System.out.println("打电话");
    }

    private void sms() {
        System.out.println("发短信");
    }
}

(3)抽象装饰类

定义如何添加手机的附加功能

public class Decorate extends MobilePhone{
    private MobilePhone mobilePhone;

    public Decorate(MobilePhone mobilePhone){
        this.mobilePhone = mobilePhone;
    }
    @Override
    void operation() {
        mobilePhone.operation();
    }
}

(4)QQ

添加QQ软件,除基础功能之外,添加QQ聊天功能

public class QQDecorate extends Decorate{
    public QQDecorate(MobilePhone mobilePhone) {
        super(mobilePhone);
    }

    @Override
    void operation() {
        super.operation();
        qq();
    }
	
    private void qq(){
        System.out.println("qq聊天");
    }
}

(4)WeChat

添加微信软件

public class WeChatDecorate extends Decorate {
    public WeChatDecorate(MobilePhone mobilePhone) {
        super(mobilePhone);
    }

    @Override
    void operation() {
        super.operation();
        chat();
    }

    private void chat() {
        System.out.println("微信聊天");
    }
}

(5)ArenaGame

添加王者荣耀软件

public class ArenaGameDecorate extends Decorate{
    public ArenaGameDecorate(MobilePhone mobilePhone) {
        super(mobilePhone);
    }

    @Override
    void operation() {
        super.operation();
        play();
    }

    private void play(){
        System.out.println("玩儿王者荣耀");
    }
}

(6)Client

实现

public class Client {
    public static void main(String[] args) {
        System.out.println("第一代手机");
        FirstGenerationPhone phone = new FirstGenerationPhone();
        phone.operation();

        System.out.println("\n安装QQ之后的功能");
        QQDecorate qqDecorate = new QQDecorate(phone);
        qqDecorate.operation();

        System.out.println("\n安装微信之后的功能");
        WeChatDecorate weChatDecorate = new WeChatDecorate(qqDecorate);
        weChatDecorate.operation();

        System.out.println("\n安装王者荣耀之后的功能");
        ArenaGameDecorate arenaGameDecorate = new ArenaGameDecorate(weChatDecorate);
        arenaGameDecorate.operation();
    }
}

效果:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值