代码码云仓库地址:https://gitee.com/dzxmy/design_pattern
常用的结构型设计模式有:适配器模式,装饰者模式,代理模式,外观模式,桥接模式,享元模式
不常用的结构型设计模式有:组合模式
一、外观模式
定义:又叫门面模式,提供了一个统一的接口,用来访问子系统中的一群接口,外观模式定义了一个高层接口,让子系统更容易使用
类型:结构型
优点:简化了调用过程,无需了解深入子系统,防止带来风险,减少系统依赖,松散耦合,更好的划分访问层次,符合迪米特法则,即最少知道原则
缺点:增加子系统、扩展子系统行为容易引入风险,不符合开闭原则
com.dzx.design.structural.facade 包下代码:外观模式
二、 装饰者模式
定义:在不改变原有对象的基础之上,将功能附加到对象上,提供了比继承更有弹性的替代方案(扩展原有对象功能)
类型:结构型
适用场景:扩展一个类的功能或给一个类添加附加职责,动态的给一个对象添加功能,这些功能可以再动态的撤销
优点:
- 继承的有力补充,比继承灵活,不改变原有对象的情况下,给对象一个扩展功能
- 通过使用不同装饰类以及这些装饰类的排列组合,可以实现不同效果
- 符合开闭原则
缺点:
- 会出现更多的代码,更多的类,增加程序复杂性
- 动态装饰时,多层装饰时
com.dzx.design.structural.decorator.v2 包下代码
三 、适配器模式
定义:将一个类的接口转换成客户期望的另一个接口 ,使原本接口不兼容的类可以一起工作
类型:结构型
使用场景:已经存在的类,它的方法和需求不匹配时(方法结果相同或类似)
不是软件设计阶段考虑的设计模式,是随着软件维护,由于不同产品,不同厂家造成功能类似而接口不相同情况下的解决方案
优点:
- 能提高类的透明性和复用,现有的类复用但不需要改变
- 目标类和适配器类解耦,提高程序扩展性
- 符合开闭原则
缺点:
- 适配器编写过程需要全面考虑,可能会增加系统的复杂性
- 增加系统代码的可读难度
com.dzx.design.structural.adapter 包下代码:适配器模式
四、享元模式
定义:提供了减少对象数量从而改善应用所需的对象的结构的方式
运用共享技术有效地支持 大量细粒度的对象
类型:结构型
使用场景:常常应用于系统底层的开发,以便解决系统的性能问题,比如java种的String类,和数据库连接池
系统有大量相似的对象,需要缓冲池的场景。
优点:减少对象的创建,降低内存中对象的数量,降低系统的内存,提高效率,减少内存之外的其他资源占用
缺点:关注内外部状态,关注线程安全问题,使系统,程序的逻辑复杂化
com.dzx.design.structural.flyweight 包下代码:享元模式
五、组合模式
定义:将对象组合成树形结构以表示“部分-整体”的层次结构
组合模式使客户端对单个对象和组合对象保持一致的方式处理
类型:结构型
适用场景:
- 希望客户端可以忽略组合对象与单个对象的差异时
- 处理一个树型结构时
优点:清楚的定义分层次的复杂对象,表示对象的全部或部分层次,让客户端忽略层次差异,方便对整个层次结构进行控制,简化客户端代码,符合开闭原则。
缺点:限制类型时会较为复杂,使设计变得更加抽象
com.dzx.design.structural.composite 包下代码: 组合模式
六、 桥接模式
定义:将抽象部分与它的具体实现部分分离,使他们都可以独立地变化
通过组合的方式建立两个类之间联系,而不是继承
类型:结构型
适用场景:
- 抽象和具体实现之间增加更多的灵活性
- 一个类存在两个(或多个)独立变化的维度,且这两个(或多个维度都需要独立进行扩展)
- 不希望使用继承,或因为多层继承导致系统类的个数剧增
优点:分离抽象部分及其具体实现部分,提高了系统的可扩展性,符合开闭原则,符合合成复用原则
缺点:增加了系统的理解与设计难度,需要正确地识别出系统中两个独立变化的维度
com.dzx.design.structural.bridge 包下代码:桥接模式
七、代理模式
定义: 为其他对象提供一种代理,以控制对这个对象的访问
代理对象在客户端和目标对象之间起到中介的作用
适用场景:保护目标对象,增强目标对象
类型:结构型
优点:
- 代理模式能将代理对象与真实被调用的目标对象分离
- 一定程度上降低了系统的耦合度,扩展性好
- 保护目标对象,增强目标对象
缺点:
- 代理模式会造成系统设计中类的数目增加
- 在客户端和目标对象增加一个代理对象,会造成请求处理速度变慢
- 增加系统的复杂度
分为静态代理 、 动态代理、CGLib代理
spring的代理选择
- 当Bean有实现接口时,spring就会用jdk的动态代理
- 当Bean没有实现接口时,spring使用cglib
- 可以强制使用cglib,在spring配置中加入<aop:aspectj-autoproxy proxy-target-class="true"/>
参考资料:https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html
静态代理编码:
com.dzx.design.structural.proxy.staticproxy 包下代码 : 静态代理模式
动态模式编码:
com.dzx.design.structural.proxy.dynamicproxy 包下代码: 动态代理模式(核心:生成代理对象,重写InvocationHandler的invoke方法)
文章来源: blog.csdn.net,作者:血煞风雨城2018,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/qq_31905135/article/details/98054279