结构型设计模式总结
前言
结构型设计模式总结。
代理模式(Proxy)
描述:
- 为其他对象提供一种代理以控制对这个对象的访问
结构:
- 抽象服务类
- 具体服务类——与抽象服务类是继承关系——被代理者
- 代理类——与抽象服务类是继承关系,与具体服务类是关联关系——代理者
关联关系和聚合关系的区别:
- 语义不同,实现相同
- 关联关系:对象间是平等的,侧重了解。如企鹅了解气候
- 聚合关系:对象间是不平等的,侧重包含。如雁群包含大雁
- 该系列博客对关联关系和聚合关系,语义上尽量用对词,实现上不再区分用词
概述:
- 抽象服务类:抽象方法
- 具体服务类:重写抽象服务类的抽象方法为具体方法
- 代理类:具体服务类对象——代理
- 代理类:重写抽象服务类的抽象方法为具体方法——代理
- 具体方法:具体服务类对象调用具体服务类的具体方法——代理过程
- 客户端:创建代理类对象(可能需要创建具体服务类对象——显式指明被代理对象),代理类对象调用代理类的具体方法
核心:
- 继承
- 多态
- 具体服务类——被代理者
- 代理类——代理者
- 代理类继承与具体服务类相同的抽象服务类——伪装成具体服务类
- 代理类对象调用代理类方法,实际上是具体服务类对象调用具体服务类方法——代理过程
- 客户端可以只知道代理类,不知道具体服务类
适配器模式(Adapter)
别名:
- 封装器模式(Wrapper)
描述:
- 将一个类的接口转换成客户希望的另外一个接口。使得原本由于接口不兼容而不能一起工作的那些类可以一起工作
类型:
- 类适配器模式:使用多继承机制: 适配器继承两个类。 只能在支持多继承的编程语言中实现, 如 C++
- 对象适配器模式:使用构成原则: 适配器继承一个类, 封装另一个类对象。 所有流行的编程语言都可以实现
类适配器模式:
结构:
- 目标类——客户端能够使用的接口——适配者
- 需适配类——客户无法使用的接口——被适配者
- 适配器类——与目标类是继承关系,与需适配类是继承关系——中间者
概述:
- 目标类:方法
- 需适配类:方法
- 适配器类:重写目标类的方法,重写需适配类的方法
- 客户端:创建目标类类型的适配器类对象,目标类类型的适配器类对象调用目标类的方法、需适配类的方法
对象适配器模式:
结构:
- 目标类——客户端能够使用的接口——适配者
- 需适配类——客户无法使用的接口——被适配者
- 适配器类——与目标类是继承关系,与需适配类是关联关系——中间者
概述:
- 目标类:方法
- 需适配类:方法
- 适配器类:需适配类对象
- 适配器类:设置需适配类对象方法,重写目标类的方法
- 设置需适配类对象方法:(创建并)设置需适配类对象为字段
- 方法:需适配类对象调用需适配类的方法
- 客户端:创建目标类类型的适配器类对象,目标类类型的适配器类对象调用方法
核心:
- 继承
- 多态
- 目标类——客户端能够使用的接口——适配者
- 需适配类——客户无法使用的接口——被适配者
- 适配器类——中间者
- 适配器类继承目标类——协调适配者
- 适配器类通过需适配类对象调用需适配类的方法——协调被适配者——适配过程
- 客户端可以只知道适配器类,不知道需适配类
外观模式(Facade)
描述:
- 为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用
结构:
- 子系统类(多个)——被管理者
- 外观类——与子系统类是关联关系——管理者
概述:
- 子系统类:方法
- 外观类:子系统类对象
- 外观类:设置子系统类对象为方法,搭配方法
- 设置子系统类对象为方法:(创建并)设置子系统类对象为字段
- 搭配方法:可以使用多个子系统类对象调用子系统类的方法——搭配多种方案
- 客户端创建外观类对象,外观类对象调用外观类的方法
核心:
- 关联关系
- 子系统类——被管理者
- 外观类封装多个子系统类对象和多个子系统类对象调用子系统类的方法
- 外观类——管理者,搭配子系统类方法的调用内容和时序/步骤
- 客户端只知道外观类,不知道子系统类
装饰模式(Decorator)
别名:
- 装饰者模式
- 装饰器模式
- 包装器模式(Wrapper)
描述:
- 动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更加灵活
结构:
- 抽象组件类
- 具体组件类——与抽象组件类是继承关系——被装饰者
- 抽象装饰类——与抽象组件类是继承关系,与抽象组件类是聚合关系
- 具体装饰类——与抽象装饰类是继承关系——被装饰者、装饰者
概述:
- 抽象组件类:抽象方法
- 具体组件类:重写抽象组件类的抽象方法为具体方法
- 抽象装饰类:设置抽象组件类类型的具体组件类对象或抽象组件类类型的具体装饰类对象方法,重写抽象组件类的抽象方法为具体方法
- 设置抽象组件类类型的具体组件类对象或抽象组件类类型的具体装饰类对象方法:(创建并)设置抽象组件类类型的具体组件类对象或抽象组件类类型的具体装饰类对象为字段
- 具体装饰类:重写抽象装饰类的具体方法为具体方法
- 具体方法:调用抽象组件类类型的具体组件类对象的具体组件类的具体方法或抽象组件类类型的具体装饰类对象的具体装饰类的具体方法
- 客户端创建具体组件类对象,创建具体装饰类对象,具体装饰类对象调用设置抽象组件类类型的具体组件类对象或抽象组件类类型的具体装饰类对象方法,具体装饰类对象调用具体装饰类的具体方法
核心:
- 继承
- 多态
- 装饰,嵌套
- 具体组件类——被装饰者
- 具体装饰类——被装饰者、装饰者
- 设置抽象组件类类型的具体组件类对象或抽象组件类类型的具体装饰类对象方法——装饰者包装被装饰者
- 具体组件类的具体方法——被装饰者的固有内容
- 具体装饰类的具体方法:调用被装饰者的具体方法——被装饰者的固有内容,装饰者的具体方法——装饰者的包装内容,搭配固有和包装的内容、时序/步骤
组合模式(Composite)
别名:
- 对象树模式(Object Tree)
描述:
- 将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性
结构:
- 组件类
- 叶子类——与组件类是继承关系——树叶
- 组合类——与组件类是继承关系,与组件类是聚合关系——树枝
概述:
- 组件类:抽象执行方法
- 叶子类:重写组件类的抽象执行方法为具体执行方法
- 组合类:组件类类型的叶子类对象或组件类类型的组合类对象集合
- 组合类:重写组件类的抽象执行方法为具体执行方法
- 组合类:添加组件方法,移除组件方法,具体执行方法
- 添加组件方法:添加组件类类型的叶子类对象或组件类类型的组合类对象到集合
- 移除组件方法:移除集合中组件类类型的叶子类对象或组件类类型的组合类对象
- 具体执行方法:遍历组件类类型的叶子类对象或组件类类型的组合类对象集合,对象调用具体执行方法
- 客户端:创建组合类对象——树根,创建组合类对象——树枝,创建叶子类对象——树叶,树枝调用添加组件方法——添加树枝或树叶,树根调用添加组件方法——添加树枝或树叶,树根调用具体执行方法
核心:
- 继承
- 多态
- 树状嵌套递归对象结构
- 客户端以相同方式处理简单和复杂元素/一致地使用单个和组合对象
其他:
- 透明方式:组件类有管理子对象的方法,如:添加组件方法、删除组件方法,组合类、叶子类的行为一致;叶子类继承和实现该些方法没有意义,违反接口隔离原则(ISP)
- 安全方式:组件类没有管理子对象的方法,组合类有管理子对象的方法
桥接模式(Bridge)
描述:
- 将抽象部分与它的实现部分分离,使它们都可以独立地变化
结构:
- 抽象实现类
- 具体实现类——与抽象实现类是继承关系
- 抽象抽象类——与抽象实现类是聚合关系
- 具体抽象类——与抽象抽象类是继承关系
概述:
- 抽象实现类:抽象方法
- 具体实现类:重写抽象实现类的抽象方法为具体方法
- 抽象抽象类:抽象实现类类型的具体实现类对象
- 抽象抽象类:设置抽象实现类类型的具体实现类对象方法,抽象执行方法
- 具体抽象类:重写抽象抽象类的抽象执行方法为具体执行方法
- 具体执行方法:抽象实现类类型的具体实现类对象调用具体实现类的具体方法
- 客户端:创建抽象抽象类类型的具体抽象类对象,抽象实现类类型的具体实现类对象,抽象抽象类类型的具体抽象类对象调用设置抽象实现类类型的具体实现类对象方法,抽象抽象类类型的具体抽象类对象调用具体执行方法
核心:
- 继承
- 多态
- 多维结构
- 合成聚合原则(C/ARP),聚合/组合
- 拆分抽象和实现,使用聚合/组合关系桥接
- 抽象:不是指抽象类和接口,指一个独立维度/类层次,如手机品牌类型
- 实现:不是指具体类和实现类,指一个独立维度/类层次,如手机软件类型
- 聚合/组合:手机品牌类对象持有手机软件类对象
- 桥接方式:手机品牌类对象通过手机软件类对象使用手机软件类的字段、方法,不必知道手机软件类的状态、行为——核心
- 无桥接方式:使用继承:每个手机品牌类有手机软件类,类的数量呈树状结构几何递增,难以维护
享元模式(Flyweight)
别称:
- 缓存模式(Cache)
描述:
- 运用共享技术有效地支持大量大量细粒度的对象
结构:
- 抽象享元类
- 具体享元类——与抽象享元类是继承关系——共享内容
- 具体不共享类——与抽象享元类是继承关系——不共享内容
- 享元工厂类——与抽象享元类是聚合关系
概述:
- 抽象享元类:抽象方法
- 具体享元类:重写抽象享元类的抽象方法为具体方法
- 具体不共享类:重写抽象享元类的抽象方法为具体方法
- 享元工厂类:抽象享元类类型的具体享元类对象或抽象享元类类型的不共享类对象表
- 享元工厂类:添加抽象享元类类型的具体享元类对象或抽象享元类类型的不共享类对象方法,返回抽象享元类类型的具体享元类对象或抽象享元类类型的不共享类对象方法
- 添加抽象享元类类型的具体享元类对象或抽象享元类类型的不共享类对象方法:(创建并)添加抽象享元类类型的具体享元类对象或抽象享元类类型的不共享类对象到表——要用才创建
- 返回抽象享元类类型的具体享元类对象或抽象享元类类型的不共享类对象方法:查表,若无创建对象,若有返回——没有才创建
- 客户端:创建享元工厂类对象,享元工厂类对象调用返回抽象享元类类型的具体享元类对象或抽象享元类类型的不共享类对象方法,以创建抽象享元类类型的具体享元类对象或抽象享元类类型的不共享类对象,抽象享元类类型的具体享元类对象调用具体享元类的具体方法,象享元类类型的不共享类对象调用不共享类的具体方法
核心:
- 继承
- 多态
- 不共享类,外部状态——不共享内容
- 共享类,内部状态——共享内容
- 共享资源、代码和实例
- 客户端传递外部状态给享元工厂类和享元类,实现不共享内容和共享内容的整合
- 拆分和整合共享内容和不共享内容
记忆
- 代理模式(Proxy):代理。代理者和被代理者接口相同,能代理。类比:快递员帮花店店员送花
- 适配器模式(Adapter):适配。适配者和被适配者接口不同,不能代理,只能适配。类比:电源适配器适配不同电压源和电器
- 外观模式(Facade):管理,搭配多种方案。类似代理模式(Proxy):客户端委托任务给外观类对象,外观类对象委托任务给多个子系统类对象。但委托者和被委托者无继承、多态:无相同接口,不能代换;有关联关系:委托者只负责管理、委托任务。类比:狼王指挥狼群
- 装饰模式(Decorator):装饰,嵌套,搭配固有和包装的内容、时序/步骤。类似外观模式(Facade)。类比:给物品包装盒子
- 组合模式(Composit):树状嵌套递归对象结构。客户端以相同方式处理简单和复杂元素/一致地使用单个和组合对象。类似装饰模式(Decorator)。类比:处理物品和包装物品盒子的方式一致
- 桥接模式(Bridge):多维结构,拆分抽象和实现,使用聚合/组合关系桥接。抽象和实现是两个独立维度,接口不同。类似代理模式(Proxy),避免组合模式(Composit)的树状结构。类比:不同手机品牌安装不同手机软件
- 享元模式(Flyweight):拆分和整合共享内容和不共享内容。类比:类似的商业网站使用同一服务器资源、代码和实例,依据网站所有者的不同具有不同的行为
参考资料
- 《大话设计模式》作者:程杰
- 常用设计模式有哪些? (refactoringguru.cn)
总结
结构型设计模式总结。
作者的话
- 感谢参考资料的作者/博主
- 作者:夜悊
- 版权所有,转载请注明出处,谢谢~
- 如果文章对你有帮助,请点个赞或加个粉丝吧,你的支持就是作者的动力~
- 文章在描述时有疑惑的地方,请留言,定会一一耐心讨论、解答
- 文章在认识上有错误的地方, 敬请批评指正
- 望读者们都能有所收获
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 夜悊的技术小宅!