结构型设计模式
一、为什么使用结构型设计模式
- 结构型模式关注点“怎样组合对象/类?”所以我们关注下类的组合关系
- 类结构型模式关心类的组合,由多个类可以组合成一个更大的(继承)
- 对象结构型模式关心类与对象的组合,通过关联关系在一个类中定义另一个类的实例对象(组合)
- 根据“合成复用原则”,在系统中尽量使用关联关系来替代继承关系,因此大部分结构型模式都是对象结构型模式。
- 适配器模式(Adapter Pattern):两个不兼容接口之间适配的桥梁
- 桥接模式(Bridge Pattern):相同功能抽象化与实现化解耦,抽象与实现可以独立升级。
- 过滤器模式(Filter、Criteria Pattern):使用不同的标准来过滤一组对象
- 组合模式(Composite Pattern):相似对象进行组合,形成树形结构
- 装饰器模式(Decorator Pattern):向一个现有的对象添加新的功能,同时又不改变其结构
- 外观模式(Facade Pattern):向现有的系统添加一个接口,客户端访问此接口来隐藏系统的复杂性。
- 享元模式(Flyweight Pattern):尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象
- 代理模式(Proxy Pattern):一个类代表另一个类的功能
二、适配器模式(Adapter Pattern)
- 将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,适配器模式分为类结构型模式(继承)和对象结构型模式(组合)两种,前者(继承)类之间的耦合度比后者高,且要求程序员了解现有组件库中的相关组件的内部结构,所以应用相对较少些
- 别名也可以是Wrapper,包装器
适配器模式(Adapter)包含以下主要角色。
- 目标(Target)接口:可以是抽象类或接口。客户希望直接用的接口
- 适配者(Adaptee)类:隐藏的转换接口
- 适配器(Adapter)类:它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口。
适配器模式(Adapter Pattern)-应用场景
-
-
Tomcat如何将Request流转为标准Request;
-
- tomcat.Request接口
- servlet.Request接口
- tomcat === CoyoteAdapte === ServletRequest
-
Spring AOP中的AdvisorAdapter是什么:增强的适配器
-
- 前置、后置、返回、结束 Advisor(通知方法)
- 底层真的目标方法
-
Spring MVC中经典的HandlerAdapter是什么;
-
- HelloController.hello()
- HandlerAdapter
- Servlet.doGet()
-
三、桥接模式(Bridge Pattern)
将抽象与实现解耦,使两者都可以独立变化
在现实生活中,某些类具有两个或多个维度的变化,如图形既可按形状分,又可按颜色分。如何设计类似于 Photoshop 这样的软件,能画不同形状和不同颜色的图形呢?如果用继承方式,m 种形状和 n 种颜色的图形就有 m×n 种,不但对应的子类很多,而且扩展困难。不同颜色和字体的文字、不同品牌和功率的汽车
桥接将继承转为关联,降低类之间的耦合度,减少代码量
商品 渠道 电商专供 线下销售 拍照手机 拍照、电商 拍照、线下 性能手机 性能、电商 性能、线下
桥接(Bridge)模式包含以下主要角色
-
- 系统设计期间,如果这个类里面的一些东西,会扩展很多,这个东西就应该分离出来
- 抽象化(Abstraction)角色:定义抽象类,并包含一个对实现化对象的引用。
- 扩展抽象化(Refined Abstraction)角色:是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法。
应用场景
- 当一个类存在两个独立变化的维度,且这两个维度都需要进行扩展时。
- 当一个系统不希望使用继承或因为多层次继承导致系统类的个数急剧增加时。
- 当一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性时。
- InputStreamReader桥接模式。An InputStreamReader is a bridge from byte streams to character streams:
- InputStreamReader 桥接+适配器
四、装饰器模式(Decorator/Wrapper(包装) Pattern)
- 适配器是连接两个类,可以增强一个类,装饰器是增强一个类
- 向一个现有的对象添加新的功能,同时又不改变其结构。属于对象结构型模式。
- 创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
应用场景
-
-
SpringSession中如何进行session与redis关联?HttpRequestWrapper
-
-
session:数据存在了内存
-
session:数据存在redis
-
HttpSession;getAttribute();
-
Wrapper(session){
-
-
-
-
- getAttribute(String param){ redis.get(param) };
-
-
-
-
}
-
-
MyBatisPlus提取了QueryWrapper,这是什么?
-
Spring中的BeanWrapper是做什么?包装了Bean。bean的功能增强?
-
Spring Webflux中的 WebHandlerDecorator?
-
已存的类,每一天在某个功能使用的时候发现不够,就可以装饰器。
-
五、代理模式(Proxy Pattern)
- 代理模式(Proxy Pattern) ,给某一个对象提供一个代理,并由代理对象控制对原对象的引用,对象结构型模式。这种也是静态代理
静态代理
JDK动态代理,其实原理就是要实现接口
Cglib动态代理,底层原理就是动态生成目标类的代理类
引用场景
-
-
MyBatis的mapper到底是什么?怎么生成的?
-
-
动态代理
-
UserMapper、CityMapper,mybatis帮我们写实现MapperProxy
-
-
- DruidDataSource存在的Proxy模式
- 监控链...
区别装饰器、代理
- 装饰器和代理之间的区别很细微,可以认为装饰器是代理的一个子集
- 静态代理就是装饰器的方式
六、组合模式(Composite Pattern)
- 把一组相似的对象当作一个单一的对象。如:树形菜单
应用场景外观模式(Facade Pattern)
- 层级结构
- 部门组织结构
- 组合了别的对象还是组合模式吗
七、外观模式(Facade Pattern)
外观(Facade)模式又叫作门面模式,是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式
应用场景
-
- 去医院看病,可能要去挂号、门诊、划价、取药,让患者或患者家属觉得很复杂,如果有提供接待人员,只让接待人员来处理,就很方便。以此类比......
- JAVA 的三层开发模式。
- 分布式系统的网关
- Tomcat源码中的RequestFacade干什么的?
八、享元模式(Flyweight Pattern)
- 享元模式(Flyweight Pattern),运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。对象结构型
- 在享元模式中可以共享的相同内容称为内部状态****(IntrinsicState),而那些需要外部环境来设置的不能共享的内容称为外部状态****(Extrinsic State),由于区分了内部状态和外部状态,因此可以通过设置不同的外部状态使得相同的对象可以具有一些不同的特征,而相同的内部状态是可以共享的。
- 在享元模式中通常会出现工厂模式,需要创建一个享元工厂来负责维护一个享元池(Flyweight Pool)用于存储具有相同内部状态的享元对象。
享元模式包含如下角色:
- Flyweight: 抽象享元类 Connection
- ConcreteFlyweight: 具体享元类 ConnectionImpl(user,pwd,url)
- UnsharedConcreteFlyweight: 非共享具体享元类ConnectionImpl(state)
- FlyweightFactory: 享元工厂类;简单工厂,产品就一个Connection
应用场景
-
- 典型的代表:数据库连接池
- 所有的池化技术
- 享元和原型模式有什么区别?享元是预先准备好的对象进行复用,原型没法确定预先有哪些
本文作者:JackWuo
本文链接:https://www.cnblogs.com/wuzhixuan/p/16328734.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步