设计模式之结构型学习

结构型

外观模式

定义:又叫门面模式,提供一个统一的接口,用来访问子系统中的一群接口,外观模式定义了一个高层接口,让子系统更容易使用

适用场景

  • 子系统越来越复杂,增加外观模式提供简单调用接口
  • 构建多层系统结构,利用外观对象作为每层的入口,简化层间调用

优点

  • 简化了调用过程,无需了解深入子系统,防止带来风险
  • 减少系统依赖,松散耦合
  • 更好的划分访问的层次
  • 符合迪米特法则,即最少知道原则

缺点

  • 增加子系统、扩展子系统的行为容易引入风险
  • 不符合开闭原则

注意事项

  • 外观模式和中介者模式区别:外观模式关注的是外界和子系统的交互,而中介者模式关注的是子系统内部之间的交互

  • 外观模式和单例模式:通常可以把外观模式的外观做成单例模式的模样,结合单例模式使用

  • 外观模式和抽象工厂模式:外观类通过抽象工厂对子系统进行调用,屏蔽子系统

源码应用:Tomcat的RequestFacade、StatemnetFacade等等

装饰者模式

定义:在不改变原有对象的基础之上,将功能附加到对象上,提供比继承更有弹性的替代方案(扩展原有对象功能)

适用场景

  • 扩展一个类的功能或给一个类添加附加的职责
  • 动态的给一个对象添加功能,这些功能可以再动态的撤销
  • 为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀,在不想增加很多子类的情况下扩展类

优点

  • 继承的有力补充,比继承灵活,不改变原有对象的情况下给一个对象扩展功能
  • 通过使用不同装饰类以及这些装饰类的排列组合,可以实现不同效果
  • 符合开闭原则

缺点

  • 会出现更多的代码,更多的类,增加程序复杂性
  • 动态装饰时,多层装饰时会更复杂

注意事项

  • 装饰者模式与代理模式:装饰者模式关注于在一个类上动态的添加方法,代理模式关注点在于控制对象的访问
  • 装饰者模式和适配器模式:都是包装模式

源码用处:jdk:java.io.BufferReader、BufferedInputStream、BufferedOutputStream

适配器模式

定义:将一个类的接口转换成客户期望的另一个接口,使原本接口不兼容的类可以一起工作

适用场景

  • 已经存在的类,它的方法和需求不匹配时(方法的结果却是相同或者相似)
  • 不是软件设计阶段考虑的设计模式,是随着软件维护,由于不同的产品、不同厂家造成功能类似而接口不相同情况下的解决方案

优点

  • 能提高类的透明性和复用,现有的类复用但不需要改变
  • 目标类和适配器类解耦,提高程序扩展性
  • 符合开闭原则

缺点

  • 适配器编写 过程需要全面考虑,可能会增加系统的复杂性
  • 增加系统代码的可读难度

注意事项

  • 类适配器和对象适配器
  • 适配器不是在详细设计时添加的,而是解决正在服役的项目的问题。

源码用处:xmlAdapter、springAop的AdvisorAdapter、servlet的HandlerAdapter

享元模式

定义:提供了减少对象数量从而改善应用所需的对象结构的方式,运用共享技术有效地支持大量细粒度的对象,以减少内存占用和提高性能,复用对象

适用场景

  • 常常应用于系统底层的开发,以便解决系统的性能问题
  • 系统有大量相似对象、需要缓冲池的场景,这些对象消耗大量内存
  • 这些对象的状态大部分可以外部化,这些对象可以按照内蕴状态分为很多组,当把外蕴对象从对象中剔除出来时,每一组对象都可以用一个对象来代替。系统不依赖于这些对象身份,这些对象是不可分辨的

优点

  • 减少对象的创建,降低内存中对象的数量,降低系统的内存,提供效率
  • 减少内存之外的其他资源占用(如:时间)

缺点

  • 关注内/外部状态、关注线程安全的问题
  • 是系统、程序的逻辑复杂化

注意事项

  • 注意划分外部状态和内部状态,否则可能会引起线程安全问题
  • 这些类必须有一个工厂对象加以控制
  • 一般用HashMap储存,储存共享对象

源码用处

  • String的字符串缓存池
  • Integer的-128~127,Integer.valueOf()
  • 各种连接池,重复使用,如:数据库连接池Druid

组合模式

定义:将对象组合成树形结构以表示”部分-整体“的层次结构,组合模式使客户端对单个对象和组合对象保持一致的方式处理,这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式。

适用场景

  • 希望客户端可以忽略组合对象与单个对象的差异时
  • 处理一个树形结构时

优点

  • 清楚地定义了分层次的复杂对象,表示对象的全部或部分层次
  • 让客户端忽略了层次的差异,方便对整个层次结构进行控制
  • 简化客户端代码
  • 符合开闭原则

缺点

  • 闲置类型时会较为的复杂
  • 使设计变得更加的抽象

注意事项

  • 定义时为具体类

源码用处

  • JDK:HashMap的addAll()方法

桥接模式

定义:将抽象部分与它的具体实现部分相分离,使它们都可以独立地变化,通过组合的方式建立两个类之间联系,而不是继承

适用场景

  • 抽象和具体实现之间增加更多的灵活性
  • 一个类存在两个(或多个)独立变化的维度,且这两个维度都需要独立进行扩展
  • 不希望使用继承,或因为多层继承导致系统类的个数剧增

优点

  • 分离抽象及其具体实现部分
  • 提高系统的可扩展性
  • 符合开闭原则,合成复用原则

缺点

  • 增加了系统的理解与设计难度
  • 需要正确的识别出系统中两个独立变化的维度
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值