您当前的位置:首页 > 计算机 > 编程开发 > 设计模式

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

时间:02-01来源:作者:点击数:

一、描述

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

角色

(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();
    }
}

效果:

在这里插入图片描述
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门