设计模式及其在项目、框架中的应用
设计模式及其在项目、框架中的应用
设计模式是软件工程中的重要概念,它提供了一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。本篇文章将介绍几种常见的设计模式及其在项目中的应用。
设计模式的作用
- 类之间关系图:明确的角色及其关系、作用;
- 符合开闭原则:职责明确,并且开放的拓展点可以有效应对后期的变化。
责任链模式
适用场景
在一个流程中,对某一个对象有一串不同的业务处理操作,可以把这些业务操作封装成一个抽象业务的不同实现类,便于在链路中动态添加处理逻辑。
类图分析
角色:请求者、处理者、处理者链路
举例
- 快麦ERP,订单进入系统后,需要进行一系列的后续处理动作:敏感信息加密、分配赠品、匹配仓库、物流方式、锁定库存,这些动作可以都抽象成对订单的操作,以链路的方式将这些动作串起来。
- Sentinel的SlotChain
Sentinel是一个流控框架,对进来的请求进行统计、限流、权限控制、降级等处理,它也做成处理链的形式,方便添加新的处理逻辑。在这里,被处理者是资源ResourceWrapper,处理者是Slot,处理者链路是SlotChain,具体的Slot实现类有NodeSelectSlot、FlowSlot等。
抽象工厂模式
适用场景
需要根据"系列名称"等来获取一系列的对象实例,这些对象实例有一个聚合的业务含义,比如都属于鞋子加工过程中用到的设备。
类图分析
角色:抽象工厂、工厂、抽象产品、产品
举例
- 快麦ERP,业务流程中需要与不同平台(淘宝、京东)交互,比如从不同平台下载订单,下载部分的代码包含平台接口请求以及转化为我们系统的订单实体的代码。我们将这些与平台相关的业务逻辑代码提取出来,作为抽象接口,在业务代码中使用的时候以PlatformAccessManager.load(平台名,业务类.class)的形式加载。PlatformAccessManager就是抽象工厂,能够根据平台名返回该平台对应的操作类。这里将操作类抽象出来的方式有模板模式的味道,只是具体的实现类不是模板的子类,而是类似策略模式里的策略类。
public class TradeDownloadService {
public void downLoad(String platform, String tid) {
DownloadBusiness downloadBusiness = PlatformAccessManager.load(platform, DownloadBusiness.class);
downloadBusiness.download(tid);
}
}
public interface DownloadBusiness {
Trade download(String tid);
}
外观模式
适用场景
封装内部的多个服务的功能,给外界提供一个统一的接口。
类图分析
角色:对外接口、内部实现类
举例
- 快麦ERP,模块一Dubbo接口的形式暴露本模块的对外功能接口,这些接口的实现中包含对本模块的服务功能的整合。
观察者模式
适用场景
事件的发布者与订阅者常常属于不同的业务模块、不同的处理线程,如何将这两者、这两个过程解耦,就是观察者模式实现的效果。一个发布者可以对应多个订阅者,一旦发布者发出通知,订阅者收到消息,便可做相应的消息处理。
类图分析
角色:主题、观察者
举例
- 消息队列
在分布式应用中,为了达到模块之间解耦、数据处理过程异步拆解的目的,常常会以消息的形式来触发过程执行,通知者和被通知者分别对应消息队列中的发布者和订阅者。比如订单生成成功后,锁定库存需要同步进行,但是订单操作日志记录的工作实时性要求不高,可以通过消息队列的形式通知进行。
代理模式
适用场景
要为一些过程增加统一的拦截处理,比如记录日志、权限验证,就可以使用代理模式。通过对实际对象的处理动作进行代理,就可以实现动作拦截、行为控制、增加统一动作的效果。
类图分析
角色:被代理接口、被代理类、代理类
举例
- 拦截器实现权限过滤