时间过得有点快,距离《浅谈代码层级与接口设计》已经有一年多了。在去年的基础上只是更加明确了代码整体的架构设计,目的快速响应了当前公司业务的需求。
代码整体架构
架构图比较简单,其实就是在Yii的架构上加了点公司的公共业务需求而已,如果业务简单common module 和 core可以合成在一起 。
架构优点
1、能灵活挑选模块组合+core进行发布
2、明确模块的职责,模块间进行解耦,单独模块更新不影响其他模块
3、在编码过程中鼓励团队中的成员能贡献更多的common代码和core代码,减少重复编码
架构缺点
1、升级core和common时,会影响所有应用
2、当模块间的相互调用时(业务间的交集),无法将应用真正的隔离
Logic层的作用
比Yii中多了logic,logic最终是给controller调用的。为什么要多此一举?
1、按照Yii的机制,controller是可以相互调用的,但很麻烦。(我承认懒得去看更多细致的文档)
Yii::$app->runAction('new_controller/new_action', $params);
虽然这句看上去也挺简单的,但是事实上相当重新跑了一次Yii中调用控制器的流程。在一些业务中,并不需要如此繁琐。再者在调用了其他控制器的方法后,也无法获取相关更多细节的信息。
2、当控制器中加上了权限控制的时候,相互调用更加直接导致了业务逻辑的复杂。举例用户A有权限(controller/action1),没有(controller/action2)的权限。当业务需求发生改变,action1需要调用到action2时。你愿意重复编码,还是和产品撕逼?
3、当面临复杂、重复、多变的业务体系时,业务代码都写在controller中,会让controller显得特别笨重。难以扩展和进行调优。
所以为了实现模块间的业务可以相互快速调用,将Controller架空,多一层Logic。需要时直接生成另一个logic的实例进行调用即可。下面的抽象类Logic的代码。
abstract class Logic{
function setCode();
function getCode();
function setData();
function getData();
function setMessage();
function getMessage();
}
Logic层需要给Controller层调用的方法,必须返回统一的状态,一般为boolean,同时需要调用setCode方法,进行设置异常的状态。在其他Logic去调用时,根据getCode就能知道调用的方法,是否正常。调用getMessage就能知道发生的细节。
在简单的业务中,是没有必要多这一层logic的,在设计上Yii的代码架构已经能满足,毕竟这是许多人的心血结晶。多了一层logic,反而让controller担任的是路由的责任,但本质上是为了让代码更加灵活,更多是为了统一的概念而设定。
1、于个人而言,令我编码更加舒适、快捷。毕竟不喜欢controller之间的调用限制和复杂。
2、代码重构(重写)变得更加方便。因为controller只是一个路由,可以任意调用logic层中方法。对于路由,是不用关心实现的细节。当代码重构上线遇到问题时,能简单改几行代码就能恢复现场。如果重构通过,就能大把大把的清理代码。看一份清晰简单的代码,会让人很爽。
3、再者业务间的相互灵活调度,能大量减少重复编码。虽然会导致业务之间的耦合,但是逻辑性的高度统一,能让你的代码逻辑更加严谨,出现bug时,能快速定位。而事实上当业务稳定明朗时,bug很少会出现。
Model层的改变
我们查询SQL时一般都是用"id,name as title"进行字段的筛选。借鉴于SQL的模式。我写了一个字段解析器(FieldParser),大体如下图:
在字段解析器中,对于额外字段,同时实现了SQL一样的"AS"重命名模式。
所以对于字段解析器优缺点很明显
优点:
1、字段扩展灵活,能快速响应业务需求。在开发中,作为后端我一直要求各端字段完全统一,但是事实上对于产品的需求,根本不可能。web端能显示信息更多也更丰富,而App端会要求更简洁。有时候,需要的字段,需要各端从其他几个接口的逻辑实现。作为后端付出多一点,能极大的提高开发整体的效率。
2、有了字段解析器后,在业务层的查询很简单,将复杂的组合性字段交还给了Model层进行实现。从而在代码层面上实现了职责的分离。这样业务(Logic)层只是专注关心于业务的逻辑,Model层也更加专注于自身,提供业务所需要的数据。在一定程度上,也降低了代码的复杂度。
3、极大的提高了开发速度。面对各种查询需求,无非就是从需要的关系表里面去查找数据,然后返回。有了字段解析器的功能,每多一个额外字段,其实就相当于往表里面动态添加字段一样简单。
缺点:
1、查询速度会慢!!!由于将一个业务的所有查询都统一到一个模型中,其中的联表,不可避免。而在列表查询时,由于是单个方法查询的实现的额外字段。当额外字段中查询越多,速度越慢。目前仅用于内部使用的系统,并发度不高,而且内部要求是首先逻辑正确,响应慢点可以接受。
小结
写了这么多,总结一下:业务(代码)分层!将不同的问题归类,然后将其统一处理,减少重复,使业务更加清晰明了,进而提高效率。
我之前写的《架构演变的探索》也是源自于这种思想,但形式的表现有太多。