软件架构设计,是通过一些手段构建出稳定的核心骨架+灵活扩展的模块,使软件能在将来不断的变更中,经受住考验。模式,可以理解为适合处理某些场景的经验,将这些经验形成通用的骨架,就形成了模式。比如23种设计模式、适合处理交互的MVC模式。
优秀框架的架构设计会在可能发生变化的地方预留切入点,让使用者通过自定义实现扩展出特性化处理,避免修改框架的核心骨架。这就是开闭原则(Open Closed Principle,OCP)。
Spring框架,希望使用动态数据源,只需自定义动态数据源类继承AbstractRoutingDataSource ,并重写(Override)determineCurrentLookupKey方法。
SpringMVC框架,希望对Request参数进行预处理,只需继承MultiActionController,并重写(Override)initBinder方法。
Jqgrid组件,希望在表格加载完成后进行一些特性化处理,只需自定义gridComplete事件的回调方法即可,同时在api中可查阅到丰富的事件支持。
看一个实例:
业务系统一般会涉及接口交互,我们设计一个简易的接口平台。基本思路为对外提供统一接口服务,内部解耦,为每个接入系统分配的服务处理类,给A系统分配AService,B系统:BService,C系统:CService。
分析:接口的处理逻辑可以大概分为5个步骤:
1、业务校验:verify()
2、报文转换为Dto:inputMsgToDto()
3、Dto转换为领域模型:dtoToDomain()
4、完成业务逻辑:doBusiness()
5、记录接口日志:saveLog()
每个接口(Service)都需要依次调用这5个步骤,而各个接口除了saveLog的实现逻辑一致之外,前4个步骤的实现逻辑各不相同,应用场景与模板方法模式很契合。
模板方法模式:
定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。
模板方法模式类图
在类图中可以看出,templateMethod()依次调用verify()、inputMsgToDto()、dtoToDomain()、doBusiness()、saveLog(),在基类中实现saveLog()供子类继承复用,定义verify()、inputMsgToDto()、dtoToDomain()、doBusiness()为抽象方法由子类去实现。清晰的划分出核心骨架:templateMethod()和灵活扩展模块:verify、inputMsgToDto等四个方法。
目前类图中只有一个子类Aservice,实际上,根据接入系统的不同,我们还会有BService、CService等继承于AbstractService的子类,客户端需要根据接入系统决定创建哪个子类实例,这时适合引入简单工厂模式。
简单工厂模式
又叫做静态工厂方法模式,属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例,创建的实例通常都具有共同的父类。
简单工厂模式类图
类图把易变的对象创建逻辑:根据icode创建相应子类的代码(红色框标注),纳入到工厂ServiceFactory中,隔离了对象创建和对象使用,减少了客户端类的复杂性,符合单一职责原则。
思考:如果不引入简单工厂,会发生什么?
答:工厂中的以下代码会存在于客户端类ClientClass中,
if(iCode.equals("ACode")){
service = new AService();
}
if(iCode.equals("BCode")){
service = new BService();
}
思考:如果增加一个接入系统C,会发生什么?
答:继承AbstractService实现CService,同时在ServiceFactory中增加以下内容:
if(iCode.equals("CCode")){
service = new CService();
}
继续把这里的变化部分处理为可配置化,由xml来维护icode与Service的关系。
简单工厂模式+配置化
至此,架构设计基本结束,扩展接口通过增加Service和xml配置即可实现,具备了一定的扩展性,也基本符合OCP原则。作为某个特定系统的接口开发组件基本够用了,但如果作为通用的接口平台产品来使用,可能需要考虑更多的变化点。如:根据icode来路由Service是否通用,是否需要将ServiceFactory设计为接口,支持使用者根据需要扩展自定义路由实现。这里认为:
对OCP原则的支持程度应结合软件的定位,特定系统的通用功能不需要按照通用产品的要求去做。
在逐步迭代设计的过程中,我们发现为了到达软件架构设计的目标:高内聚、低耦合、可灵活扩展,根据具体的场景,我们需要组合使用一系列的设计模式,并遵循OCP、单一职责等原则。即:需求驱动我们使用设计模式,需求驱动我们遵循软件设计原则。
参考链接:
[http://www.iigrowing.cn/shu_ju_liu_tu_dfd_jian_jie.html]:
http://www.iigrowing.cn/shu_ju_liu_tu_dfd_jian_jie.html
[https://www.csdn.net/gather_2a/MtTacg2sMTYzMS1ibG9n.html]: https://www.csdn.net/gather_2a/MtTacg2sMTYzMS1ibG9n.html
[https://www.csdn.net/gather_2a/MtTacg2sMTYzMS1ibG9n.html]: https://blog.csdn.net/hu19930613/article/details/82708292
网友评论