专栏首页技术趋势设计模式-装饰器模式

设计模式-装饰器模式

背景

现代人每个人基本都会有一部手机,有的有好几部,正常情况下买手机有很多套餐,比如裸机、裸机+贴膜、裸机+贴膜+手机壳等,但是不一定每个人在购买的时候都一定会贴膜,所以个性化需求就出来了,所以这个贴膜,总不能一出厂就有了,一般后续服务中增加的,属于装饰品,而装饰器模式就解决该问题。

装饰器模式是什么?

定义:装饰器动态给一个对象添加一些额外的功能/职责,装饰模式比生成子类更为灵活。 抽象构件(component)角色 :用来规范被装饰的对象,一般为统一接口输出。具体构件(concreteComponent )角色 :被装饰的类,本身也是具备功能类。装饰(decorator)角色 :持有一个构件对象的实例。并定义一个跟抽象构件一致的接口。具体 (concreteDecorator ) 装饰角色 :负责给具体构件添加附加职责的类。在实际使用中多数情况下装饰角色和具体装饰角色可能由一个类来承担。其实也就是给你手机加些装饰器,而这些装饰器可有可无,根据你的选对来的,贴不贴膜,要不要手机壳,非原厂出厂就有。

装饰器模式可以干嘛?

对原有的对象或者功能动态增加功能/职责,很好的起到一个动态增删。并且代码不会浸入性低,新增的功能增减不会影响原来的功能;
就比如一部手机买到手是裸机,新贴上膜和手机壳,不会影响这个手机的使用,并且这个壳和膜不想用不会影响手机的功能。

优点:

代码易读:使用装饰器模式代码简单易读,业务逻辑清晰; 拓展性强:功能动态增删影响低; 减少耦合,低侵入:由于解决了传统的继承或者说在原来的对象去增加功能减少了很大的耦合和侵入性也很少;

缺点:

多层装饰导致系统复杂:因为如果装饰器可以有好多层所以会导致系统过于复杂,所以建议不要过于复杂的装饰。

装饰器类图

实现代码

源码下载:https://gitee.com/hong99/design-model/issues/I1IMES

/**
 * @Auther: csh
 * @Date: 2020/5/28 18:02
 * @Description:抽象的手机
 */
public interface IPhone {
    //打电话
    void callUp(String number);
    //上网
    void internet(int newWork);
    //基本功能
    void printFunction();
}
/**
 * @Auther: csh
 * @Date: 2020/5/28 18:06
 * @Description:小米手机
 */
public class XMPhone implements IPhone {
    @Override
    public void callUp(String number) {
        System.out.println("小米手机打电话:"+number);
    }

    @Override
    public void internet(int newWork) {
        System.out.println("上的网络"+newWork+"G");

    }

    @Override
    public void printFunction() {
        System.out.println("小米手机有手电话和上网功能");

    }
  }

/**
 * @Auther: csh
 * @Date: 2020/5/28 18:05
 * @Description:华为手机
 */
public class HWPhone implements IPhone {
    @Override
    public void callUp(String number) {
        System.out.println("正在打电话:"+number);

    }

    @Override
    public void internet(int newWork) {
        System.out.println("上的网络"+newWork+"G");
    }

    @Override
    public void printFunction() {
        System.out.println("华为手机有手电话和上网功能");
    }
}
/**
 * @Auther: csh
 * @Date: 2020/5/28 18:07
 * @Description:抽象的修饰器
 */
public abstract class IPhoneDecorator implements IPhone  {
    protected IPhone phone;

    public IPhoneDecorator(IPhone phone) {
        this.phone = phone;
    }

    @Override
    public void printFunction() {
        phone.printFunction();
    }
}
/**
 * @Auther: csh
 * @Date: 2020/5/28 18:10
 * @Description:手机壳装饰器
 */
public class PhoneShellDecorator extends IPhoneDecorator {
    public PhoneShellDecorator(IPhone phone) {
        super(phone);
    }



    @Override
    public void callUp(String number) {
        phone.callUp(number);
    }

    @Override
    public void internet(int newWork) {
        phone.internet(newWork);
    }

    @Override
    public void printFunction() {
        super.printFunction();
        this.setShell();
    }

    private void setShell(){
        System.out.println("加装了手机壳");
    }
}
/**
 * @Auther: csh
 * @Date: 2020/5/28 18:10
 * @Description:
 */
public class PhoneFilmDecorator extends IPhoneDecorator {
    public PhoneFilmDecorator(IPhone phone) {
        super(phone);
    }



    @Override
    public void callUp(String number) {
        phone.callUp(number);
    }

    @Override
    public void internet(int newWork) {
        phone.internet(newWork);
    }

    @Override
    public void printFunction() {
        super.printFunction();
        this.setFilm();
    }

    private void setFilm(){
        System.out.println("贴了膜");
    }
}
/**
 * @Auther: csh
 * @Date: 2020/5/28 18:16
 * @Description:案例
 */
public class Client {

    public static void main(String[] args) {
        HWPhone hwPhone  = new HWPhone();
        hwPhone.printFunction();
        PhoneFilmDecorator phoneFilmDecorator = new PhoneFilmDecorator(hwPhone);
        XMPhone xmphone = new XMPhone();
        phoneFilmDecorator.printFunction();
        PhoneShellDecorator phoneShellDecorator = new PhoneShellDecorator(xmphone);
        phoneShellDecorator.printFunction();
    }
}

结果

华为手机有手电话和上网功能
华为手机有手电话和上网功能
贴了膜
小米手机有手电话和上网功能
加装了手机壳

源码下载:https://gitee.com/hong99/design-model/issues/I1IMES

最后

装饰器在日常开发过程中应用广泛,比如类似这种需求迭代比较快,而又不确定这个属性/方法是否以后会一直保留,在这种不确定性的场景下装饰器再适合不过了。或者说原来的功能已很稳定不想影响到原来的功能,并且该功能只是个性化给某个需求专用,那就建议使用。

本文分享自微信公众号 - 技术趋势(jishuqs),作者:逍遥壮士

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-06-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 设计模式-责任链模式

    基本每个在职人员,都经历过请假的事情。正常情况下,请假需要经过上级部门领导审批,而公司有总经理、部门经理、组长 有的甚至更多职位。请假也分为很多种情况,比如,事...

    逍遥壮士
  • 设计模式-前端控制器模式

    记得在java里面写过html代码的同学,痛苦大家都知道,想拓展,同样一份代码维护性和继承性可以说真的把java三种特性彻底搞没了,而且,还他xxx难维护。

    逍遥壮士
  • 设计模式-外观模式

    一般想DIY电脑个性人配置,要么自己来组装(很费劲),要么买在电脑城买好组件找师师傅帮你装,不用理那么多,而外观模式就是类似这种为你组装好的人员。

    逍遥壮士
  • Android设计模式一

    模式定义 定义一个操作中的算法的骨架(稳定),而将一些步骤延迟(变化)到子类中。Template Method使子类可以不改变(复用)一个算法的结构即可重定义...

    爱因斯坦福
  • 设计模式---05.访问者模式

    访问者模式是一种对象和对象的访问者分开的一种设计模式,在一个对象稳定的情况下,使用访问者模式可以更好的扩展对数据的访问。 相当于是我们在对象里面安插了一个“眼...

    付威
  • 在线教育平台开发中,如何接入sdk实现小班课

    在线教育平台开发过程中,有些功能并不是通过公司一手打造的,而是通过接入第三方实现的,因为相比于重新开发,接入第三方反而更加保险和稳定,接下来,小编将以声网sdk...

    万岳教育系统
  • Android登录代码MVP架构详解

    砸漏
  • Android Architecture Components(2)

    Android Architecture Components是google官方提供的一套架构组件,用于设计构建更加稳健,可测试和易维护的应用,在Android...

    小海编码日记
  • Netty入门(Netty4.x使用指南)

    现如今,我们使用通用的应用程序或库来相互通信。例如,我们经常使用HTTP客户端库从服务器上获取信息并通过web服务执行远程过程调用。但是,通用协议或它的实现有时...

    小诸葛
  • Netty入门(Netty4.x使用指南)

    现如今,我们使用通用的应用程序或库来相互通信。例如,我们经常使用HTTP客户端库从服务器上获取信息并通过web服务执行远程过程调用。但是,通用协议或它的实现有时...

    小诸葛

扫码关注云+社区

领取腾讯云代金券