结构型模式
这些设计模式关注类和对象的组合。 继承的概念被用来组合接口和定义组合对象获得新功能的方式。
适配器模式
- 简介
作为两个不兼容的接口之间的桥梁。 它结合了两个独立接口的功能。
- 优点:
- 可以让任何两个没有关联的类一起运行。
- 提高了类的复用。
- 增加了类的透明度。
- 灵活性好。
-
缺点: 过多地使用适配器,会让系统非常零乱,不易整体进行把握。 比如,明明看到调用的是 A 接口,其实内部被适配成了 B 接口的实现,
- 示例
场景:书本与电子书的翻页方式。
桥接模式
- 简介
桥接是用于把抽象化与实现化解耦,使得二者可以独立变化。 这种模式涉及到一个作为桥接的接口,使得实体类的功能独立于接口实现类。这两种类型的类可被结构化改变而互不影响。
- 优点:
- 抽象和实现的分离。
- 优秀的扩展能力。
- 实现细节对客户透明。
缺点:桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程。
- 示例
场景:图片和视频的存储服务,与实现存储的功能接口
组合模式
- 简介
用于把一组相似的对象当作一个单一的对象。 组合模式依据树形结构来组合对象,用来表示部分以及整体层次。
- 优点:
- 高层模块调用简单。
- 节点自由增加。
-
缺点:在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。
- 示例
场景:表单由多个表单元素组合而成。
过滤器模式
- 简介
使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来。 它结合多个标准来获得单一标准。
- 优点:
- 简单,解耦,使用方便。
-
使用场景:需要进行筛选时。
- 示例
场景:用户分为男女,单身非单身,成年未成年;需要过滤集合中的成年单身女性用户。
装饰器模式
- 简介
向一个现有的对象添加新的功能,同时又不改变其结构。 这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
- 优点:
- 装饰类和被装饰类可以独立发展,不会相互耦合。
- 是继承的一个替代模式。
- 可以动态扩展一个实现类的功能。
-
缺点:多层装饰比较复杂。
- 示例
场景:买商品需要付邮费。
外观模式
- 简介
隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口。 这种模式涉及到一个单一的类,该类提供了客户端请求的简化方法和对现有系统类方法的委托调用。
- 优点:
- 减少系统相互依赖。
- 提高灵活性。
- 提高了安全性。
-
缺点:不符合开闭原则,如果要改东西很麻烦,继承重写都不合适。
- 示例
场景:PC系统启动与关闭。
享元模式
- 简介
减少创建对象的数量,以减少内存占用和提高性能。 尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象(工厂模式)。
- 优点:
- 大大减少对象的创建,降低系统的内存,使效率提高。
-
缺点:提高了系统的复杂度,需要分离出外部状态和内部状态,而且外部状态具有固有化的性质,不应该随着内部状态的变化而变化,否则会造成系统的混乱。
- 示例
场景:双色球生成红球和篮球。
代理模式
- 简介
一个类代表另一个类的功能。
- 优点:
- 职责清晰。
- 高扩展性。
- 智能化。
- 缺点:
- 由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。
- 实现代理模式需要额外的工作,有些代理模式的实现非常复杂。
- 示例
场景:composer包,下载国内阿里云代理的镜像源中的软件包。
流式接口
- 简介
通常通过使用方法级联来中继后续调用的指令上下文来实现。
- 优点:
- 代码的可读性提高。
- 缺点:
- 由于使用了方法级联, 因此在调用过程很长的方法级联时,文件行数会激增。
- 示例
场景:QueryBuilder的数据库查询语言生成功能。
数据映射器
- 简介(非经典设计模式)
数据映射器是一个数据访问层。 标是保持内存中的表示形式和持久性数据存储区彼此之间以及数据映射器本身之间相互独立。
- 优点:
- 数据模型遵循单一职责原则。
- 数据模型都在一个地方定义,更容易更新和维护,也利于重用代码。
- 缺点:
- 需要花很多精力学习和设置数据访问层。
- 示例
场景:ORM/DAO
依赖注入
- 简介(非经典设计模式)
IoC(控制反转)的最常见的实现方式。 由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。 许多框架已经具有用于依赖注入的容器,这些容器可通过配置数组创建对象并将其注入到需要的位置。
- 优点:
- 实现更好的可测试,可维护和可扩展的代码,实现松散耦合的体系结构。
- 缺点:
- 依赖过多会有很多参数需要在构造函数或方法中注入;创建依赖对象,使代码维护不太易。
- 示例
场景:数据库连接依赖数据库配置信息。