一、背景
随着公司业务需求的不断增加、三方合作不断接入、新APP快速产出,就会出现想在原有的代码中想增加新的业务和功能,怕影响老逻辑,想不影响老逻辑,去扩展又扩展不了的局面,就需要对应用的架构做相关的设计和优化,使可以快速复用扩展、减少网状耦合、减少开发时间成本、减少测试成本等。基础框架架构就是为解决这些问题所设计的。
二、设计
对公司业务、功能及三方合作相关内容进行梳理分析,然后对相关模块进行切割分层。我们的基础框架架构设计思路是按照纵向切割,横向切割及立体扩展三方面下手:
基于纵向切割:针对各业务模块、各功能模块的单一业务和单一功能进行封装,防止对于非自己职责范围的业务和功能的依赖。
基于横向切割:针对业务层级,功能层级、基础依赖层级进行分层,方便使用者从不同的层级去集成。
基于立体扩展:方便快速集成扩展输出APP。
基础框架架构设计各分层说明如下:
- 业务模块层:针对业务逻辑、功能模块、Ui组件及此业务所设计的数据模型之间的交互封装管理。
- 功能模块层:针对三方接口及协议的统一封装,使得接入透明化。
- UI组件层:针对常用UI通用组件封装。
- 基础支撑层:依赖的三方合作接口及sdk。
具体基础框架架构设计如下图所示:
三、实现
对上图的基础框架架构设计的基础功能模块层,UI组件层及业务模块层相关分层实现细节及注意事项详细说明,具体如下:
1.基础支撑层
整个应用开发的最小单元,主要是应用中依赖的相关三方库及api接口等,做开发的同学都知道,不做过多说明。
2.基础功能模块层
对基础支撑层中各种凌乱的三方库功能进行归类分析,对于同类的功能抽象统一的接口、协议,减少开发者对各种三方库接口的接入成本及对三方库的对象的耦合度,开发者只需要了解抽象出来的接口及输入输出数据模型。关注点如下:
- 抽象同类型同功能的三方接口协议
- 接口及模块设计专注单一功能
- 做到使用者对三方接口的使用透明化
具体实现如下图三方授权登陆功能模块所示:
3.UI组件模块层
对常用的UI组件进行封装,方便各个业务或者应用的复用、减少大量相同View对象的创建数量,这个使用可以参考设计模式中的享元模式。关注点如下:
- 避免View重复创建、销毁,增加系统内容内存开销
- 由于生命周期可能不一致,View变化的管理与创建销毁的管理分开
具体实现如下图示例所示:
4.业务逻辑层
由于业务需求是随时随地不断变化的,所以这层的设计要做到在不修改原有业务的基础上可以对业务扩展和复用,在把业务逻辑、业务视图、业务数据模型等进行封装,并且在封装的时候要分析清楚哪些是不可变的的元素,哪些是可变的元素,把不可变的元素进行封装,可变的元素进行抽象,方便后期需求变化扩展。关注点如下:
- 模块业务专注单一
- 分析出不变因素与可变因素
- 模块接口简单清晰,方便接入
- 不变的东西尽可能封装
具体实现如下图示例所示:
5.基础框架立体分层
基础框架的设计目的,就是为了快速输出APP,然而基础框架不可能满足所有新的app的需求,就需要对现有基础框架中不满足需求的功能层、UI层、业务层进行扩展实现,以满足现有业务的需求,关注点如下:
- 基础架构框架:首张图中所设计的内容,主要是一些基础功能的封装,相关基础业务的抽象等。
- 业务APP扩展框架:对基础框架层的依赖及不满足需求的业务和功能的扩展。
- APP层:组合封装输出新的APP应用
具体实现如下图示例所示:
6.架构层级封装依赖调用
在架构设计过程中调用时序也是非常重要的,关注点如下:
- 避免下层调用上层
- 避免同层级互相持有调用
- 避免隔层持有调用
- 少使用网状结构,多使用星状结构
具体调用时序示例:
四、架构优化注意事项
- 无论封装什么样的模块,注意这几个设计原则:合成复用、开闭原则、里氏替换,依赖倒置、单一职责、接口隔离原则、迪米特法则(有成熟的设计模式可以套用)。
- 使用简单化、耦合减少化、复用扩展化。
- 封装的模块最好使用自己的输入输出模型,防止过多依赖,不能即拿即用,破坏封装性。
- 分清楚要用is a还是has a,方便使用组合还是继承。
- 避免生搬硬套、过于理想主义(蜘蛛非要扩展个蜘蛛侠,哪也没招)。