包装模式(修饰器模式)

对象增强的方式

  • 继承

    • 继承父类,子类扩展
  • 装饰器模式
    • 使用“包装”的方式来增强对象
  • 代理模式
    • 代理模式
    • 或者看我代理模式的笔记。

继承

​ 最简单的方式就是继承父类,子类扩展来达到目的。虽然简单,但是这种方式的缺陷非常大

  • 如果父类是带有数据、信息、属性的话,那么子类无法增强。
  • 子类实现了之后需求无法变更,增强的内容是固定的。

举例:

当时想要自己写一个简易的JDBC连接池,连接池由List<Connection>来管理。显然我们的对象是Connection,当写到close()方法的时候卡住了。因为我们想要的功能是:调用close()是让我们的Connection返回到“连接池”(集合)中,而不是关闭掉。此时我们不能使用继承父类的方式来实现增强。因为Connection对象是由数据库厂商来实现的,在得到Connection对象的时候绑定了各种信息(数据库的username、password、具体的数据库是啥等等)。我们子类继承Connection是无法得到对应的数据的!就更别说调用close()方法了。

所以,我们可以看到子类继承父类这种方式来扩展是十分局限的,不灵活的~因此我们就有了装饰模式

继承方式实现

  • 先写一个基本功能接口

    public interface Phone {// 可以打电话void call();
    }
    
  • 写一个类去实现基本功能接口

    public class IphoneX implements Phone {    @Override    public void call() {        System.out.println("打电话给周围的人关注公众号Java3y");    }
    }
    
  • 写一个类继承基本功能然后进行增强

    public class MusicPhone extends Phone {// 听彩铃public void listenMusic() {System.out.println("我怀念的是无话不说,我怀念的是一起做梦~~~~~~");}@Overridepublic void call() {// 在打电话之前听彩铃listenMusic();super.call();}
    }
    
  • 后续一样,想要再增强,再继承一个类

// 这里继承的是MusicPhone类
public class GiveCurrentTimePhone extends MusicPhone {// 给出当前的时间public void currentTime() {System.out.println("当前的时间是:" + System.currentTimeMillis());}@Overridepublic void call() {super.call();// 打完电话提示现在的时间是多少啦currentTime();}
}

特点很明显需要去实现什么就继承什么类,缺点也很明显:

  • 我不想听彩铃了,但是我还想要看时间,做不到~
  • 我想要听彩铃前看下时间,做不到~
  • 需求变动很大,但是我要实现的功能很小不需要其他功能的时候,仍旧要继承一堆的类

包装/装饰器模式实现

  • 先写一个接口代表类的基本功能,比如打电话。

    public interface Phone {void call();
    }
    
  • 然后写一个类继承他

public class IphoneX implements Phone{@Overridepublic void call(){System.out.println("给漂亮的女孩子打了个电话,但是未接通...");}
}
  • 写一层修饰类,然后修饰类记得要拿到传递的类然后递交给上一层:
public class PhoneDecorate implements Phone{private Phone phone;
//    这边是对方法进行了重写public  PhoneDecorate(Phone phone) {this.phone=phone;}
//    调用phone的call方法@Overridepublic void call() {phone.call();}
}
  • 写功能增强,这里是彩铃~
public class MusicPhone extends PhoneDecorate{public void music(){System.out.println("啊嘶嘚啊嘶嘚~选自《忐忑》");}public MusicPhone(Phone phone){super(phone);}@Overridepublic void call(){music();super.call();}
}
  • 写功能增强,这里是获取当前时间~
public class GetCurrentTimePhone extends PhoneDecorate{public GetCurrentTimePhone(Phone phone) {super(phone);}public void getCurrentTime(){SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式System.out.println(df.format(new Date()));// new Date()为获取当前系统时间}@Overridepublic void call(){super.call();getCurrentTime();}
}
  • 写测试类去测试流程

    public class TestDecoratorPhone {public static void main(String[] args) {Phone  iphoneX = new IphoneX();iphoneX=new MusicPhone(iphoneX);iphoneX=new GetCurrentTimePhone(iphoneX);iphoneX.call();}
    }

总体脉络和文件:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ysMhMmxr-1623220113001)(1623208329323.png)]

装饰模式的优缺点:

优点

  • 装饰类和被装饰类是可以独立的,低耦合的。互相都不用知道对方的存在

  • 装饰模式是继承的一种替代方案,无论包装多少层,返回的对象都是is-a的关系(上面的例子:包装完还是Phone类型)。

  • 实现动态扩展,只要继承了装饰器就可以动态扩展想要的功能了。

缺点

  • 多层装饰是比较复杂的,提高了系统的复杂度。不利于我们调试~

代理模式很容易和修饰器模式弄混,我这里提一嘴:

相同点:

  • 二者都能对功能进行增强
  • 在静态代理模式下需要传递对象,这里和修饰器模式很类似,但值得注意的一点是装饰器模式的对象从没变过,而静态模式变过。

不同点

  • 装饰器模式是在功能外增强,并不会影响你这个类,原本是什么类最后也还是什么类。代理模式使用后,类会改变,不是原本的类了,而是代理的类。
  • 装饰器模式仅仅提供功能增强不会增强的类有所牵制。代理模式会对类施加控制, 并不提供对象本身的增强功能,而是使用代理后的对象进行的增强。

需要看装饰器模式的可以看我的这个文章:装饰器模式

在这,我给上,所有模式的代码:github地址

希望能得到大家的star

设计模式系列《包装模式》相关推荐

  1. 设计模式系列——克隆模式

    设计模式系列--克隆模式 前言 native关键字 原型模式适用的场景 原型模式的应用 原型模式实战 浅克隆 深克隆 前言 在我们工作中经常能遇到大幅度使用get或set方法,例如下面这样的代码 pu ...

  2. plsql执行command命令控制台出现乱码_设计模式系列 — 命令模式

    点赞再看,养成习惯,公众号搜一搜[一角钱技术]关注更多原创技术文章.本文 GitHub org_hejianhui/JavaStudy 已收录,有我的系列文章. 前言 23种设计模式速记 单例(sin ...

  3. 设计模式系列-创建者模式

    为什么80%的码农都做不了架构师?>>>    一.上篇回顾 上篇我们主要讲述了抽象工厂模式和工厂模式.并且分析了该模式的应用场景和一些优缺点,并且给出了一些实现的思路和方案,我们现 ...

  4. 设计模式系列-代理模式

    为什么80%的码农都做不了架构师?>>>    一.上篇回顾 很久没有更新设计模式系列的文章了,有了很多热心朋友的反馈,我决定继续将这个系列赶快写完,最近由于过年了,有很多相关的事宜 ...

  5. PHP设计模式系列 - 外观模式

    外观模式 通过在必需的逻辑和方法的集合前创建简单的外观接口,外观设计模式隐藏了调用对象的复杂性. 外观设计模式和建造者模式非常相似,建造者模式一般是简化对象的调用的复杂性,外观模式一般是简化含有很多逻 ...

  6. 策略模式和工厂模式的区别_设计模式系列 — 策略模式

    点赞再看,养成习惯,公众号搜一搜[一角钱技术]关注更多原创技术文章. 本文 GitHub org_hejianhui/JavaStudy 已收录,有我的系列文章. 前言 23种设计模式速记 单例(si ...

  7. 设计模式系列 - 解释器模式

    解释器模式通过实现一个表达式接口,从而能够以指定方式解析指定内容 介绍 解释器模式属于行为型模式,通过这种设计模式,我们可以定义一种特定的解释器来解释特定的业务场景,可以类比不同的编程语言的编译器需要 ...

  8. 设计模式系列-组合模式

    今天下班客厅的灯确实亮堂了许多,照照镜子感觉自己一下苍老许多,看来还是灯光暗比较好,看不出来自己的憔悴啊,哈哈,其实还是头发长了,决定出去剪发. 进到美发店,便有热情的服务生招呼,显示洗头,挑选造型师 ...

  9. 小米设计模式系列--proxy模式

    好久没更博了,因为最近忙着学h5和安卓,驱动只看了看wifi,这个就路漫漫其修远兮了,不知道得看到何年何月.决定把前段时间学的设计模式整理下,我是个米粉,曾一直想着去小米公司工作,不过最近买了一款红米 ...

  10. 设计模式系列-建造者模式

    快乐技术沙龙即将一周岁了,最近它又多了个妹妹叫<嗨皮吧>,春哥(秦春林)还是很给力啊!一连搞两个组织(社团 (∩_∩)),那么还是主要介绍一下妹妹嗨皮吧好啦,说起嗨皮吧还真是有很多吸引人的 ...

最新文章

  1. 银联配置 linux 路径,深圳银联POS支付系统安装手册(LinuxMySQL).doc
  2. BAT技术专家的4个考核点!
  3. 院士论坛|李德仁:测绘遥感与智能驾驶
  4. 轻松学习LINUX系列教程推出
  5. python字符串、列表和文件对象总结
  6. leetcode C++ 13. 罗马数字转整数 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。
  7. CSS设置动态超链接
  8. 第六章 hbase shell 命令
  9. linux解压war包的命令
  10. vue中Router的封装以及使用
  11. python必背入门代码-初学Python必背手册
  12. 时间片轮转调度算法模拟(Linux-C语言)
  13. 电商大数据“杀熟”套路有哪些
  14. DirectX11海洋模拟实践
  15. web前端学习基础教程,简单的图片旋转木马自动轮播js代码
  16. 【GoCN酷Go推荐】ip2location 解析 IP 地址库
  17. [BZOJ3161]孤舟蓑笠翁
  18. 书论94 梁同书《频罗庵论书》
  19. 机器学习和人工智能发展简史
  20. oracle 根据出生年份计算生肖

热门文章

  1. 重启oracle ora-01033,解决连接ORACLE错误一例:ORA-01033: ORACLE 正在初始化或关闭 | 学步园...
  2. MacOS 安装 Maven
  3. swift编程语言中文版
  4. 智慧校园大数据云平台(2)
  5. Win32API实现的欢乐小程序
  6. Android O Doze模式的状态
  7. Android 8.1 Doze模式分析(一)
  8. Ghost Win10 TH2正式版10586简体中文64位专业版
  9. mysql连接hostname_使用hostname方式连接数据库!
  10. 计算机CAD制图的概念,BIM是什么?与传统绘图软件CAD有什么差别呢?