代理模式
意图
代理模式是一种结构型设计模式, 让你能够提供对象的替代品或其占位符。 代理控制着对于原对象的访问, 并允许在将请求提交给对象前后进行一些处理。
优点
-
你可以在客户端毫无察觉的情况下控制服务对象。
-
如果客户端对服务对象的生命周期没有特殊要求, 你可以对生命周期进行管理。
-
即使服务对象还未准备好或不存在, 代理也可以正常工作。
-
开闭原则。 你可以在不对服务或客户端做出修改的情况下创建新代理。
缺点
- 代码可能会变得复杂, 因为需要新建许多类。
- 服务响应可能会延迟。
应用场景
-
延迟初始化 (虚拟代理)。 如果你有一个偶尔使用的重量级服务对象, 一直保持该对象运行会消耗系统资源时, 可使用代理模式。
-
访问控制 (保护代理)。 如果你只希望特定客户端使用服务对象, 这里的对象可以是操作系统中非常重要的部分, 而客户端则是各种已启动的程序 (包括恶意程序), 此时可使用代理模式。
-
本地执行远程服务 (远程代理)。 适用于服务对象位于远程服务器上的情形
-
记录日志请求 (日志记录代理)。 适用于当你需要保存对于服务对象的请求历史记录时。
-
缓存请求结果 (缓存代理)。 适用于需要缓存客户请求结果并对缓存生命周期进行管理时, 特别是当返回结果的体积非常大时。
-
智能引用。 可在没有客户端使用某个重量级对象时立即销毁该对象。
实践
- 业务系统的非功能性需求开发
- 比如:监控、统计、鉴权、限流、事务、幂等、日志。
- RPC 框架也可以看作一种代理模式
- 远程代理。通过远程代理,将网络通信、数据编解码等细节隐藏起来
- 缓存代理
- 动态代理、AOP切面
桥接模式
意图
****桥接模式**是一种结构型设计模式, 可将一个大类或一系列紧密相关的类拆分为抽象和实现两个独立的层次结构, 从而能在开发时分别使用。
优点
-
你可以创建与平台无关的类和程序。
-
客户端代码仅与高层抽象部分进行互动, 不会接触到平台的详细信息。
-
开闭原则。 你可以新增抽象部分和实现部分, 且它们之间不会相互影响。
-
单一职责原则。 抽象部分专注于处理高层逻辑, 实现部分处理平台细节。
缺点
- 对高内聚的类使用该模式可能会让代码更加复杂。
应用场景
-
如果你想要拆分或重组一个具有多重功能的庞杂类 (例如能与多个数据库服务器进行交互的类), 可以使用桥接模式。
-
如果你希望在几个独立维度上扩展一个类, 可使用该模式。
-
如果你需要在运行时切换不同实现方法, 可使用桥接模式。
实践
-
JDBC 驱动
- JDBC 本身就相当于“抽象”,具体的 Driver(比如,com.mysql.jdbc.Driver)就相当于“实现”。JDBC 和 Driver 独立开发,通过对象之间的组合关系,组装在一起。JDBC 的所有逻辑操作,最终都委托给 Driver 来执行。
-
API 接口监控告警
- 通知的紧急程度有多种类型,不同的通知渠道;我们将不同渠道的发送逻辑剥离出来,形成独立的消息发送类。通知类相当于抽象,消息发送类相当于实现,两者可以独立开发,通过组合关系(也就是桥梁)任意组合在一起。