来源:黄亿华 ,
my.oschina.net/flashsword/blog/278557
1. 经历的几种业务架构的方式
公司是典型的SOA架构,Web层之下就是远程Service。Web层负责调用Service,Service则在内部整合缓存、数据库等内容,实现业务逻辑。
这样的结构没有什么问题,问题就在于Service内部的实现上。即使是Service的一个方法,内部实现也可能很复杂,这就涉及到代码分解的问题。
例如:在一个SNS系统中,我有一个UserService,负责User的CRUD。当然实际逻辑会比较复杂,例如新建User要创建用户,还要初始化积分、等级、收件箱等内容。那么,我该怎么做这件事呢?
public interface UserService {
public boolean addUser(UserDTO userDTO);
public boolean updateUser(UserDTO userDTO);
public UserDTO getUser(int id);
public boolean deleteUser(int id);
}
1.1 随意拆分式
我们之前的结构很随意,大部分代码都直接写在Service的实现类中,Service直接访问Dao实现逻辑。如果过于复杂,则会拆分成一些小的内部Service,并把它们聚合起来。这种方式在业务不复杂的时候,其实工作的还挺好的。
1.2 水平分层式
新接手的项目,老实说业务会更复杂。之前的做法是将业务分为了dal-数据库访问、domain-领域模型抽象、biz-业务逻辑、service-服务集成四层。例如一个查询数据的操作,可能要经历这么多个分层的流转,才能最终提供外部服务。这样分下来,代码的全复杂度确实也低了不少。
但是这个划分导致我接手项目的时候困惑了很久,导致我觉得自己是不是理解能力下降了。后来在着手重构的时候,发现其实很多层次边界根本就很模糊了,甚至连参与维护者也不是很清楚。
过多的分层,会增加坏代码的破坏力,如果边界不是足够清晰,那就不如不分。
我理想的水平分层其实Web-Service-Dao已经足够了,因为他们的边界相对清晰,直接把Dao当做模型也工作得挺好,抽象出Domain来,根据已有的经验略微多余。
1.3 垂直拆分式
今天在做另一个项目的时候,尝试用一个责任链的方式来做这个事情。采用了垂直拆分的方式,将完成一件事,按照不同的模型,进行了细分,分成多个Processor,接口类似下面这样。Service内部只对这些子Processor做链式调用,它甚至也不知道有多少个Processor。结果这种方法出奇的好,大家发现并行开发很方便,测试也好写了,修改也方便了。
public interface Processor {
public void onAdd(UserDTO userDTO);
public void onUpdate(UserDTO userDTO);
public void onDelete(UserDTO userDTO);
}
2. 结论:几个架构的检验标准
经过多次的折腾,也接手过不少的项目,我得出这么几个结论:
2.1 一段逻辑,要能让别人轻松的定位到代码在哪里
这是我参与了很多项目的感受。好的结构并不需要跟踪很多代码层次,才能发现其中的逻辑到底在哪里。相反坏的架构可能有很多层抽象,单个复杂度不高,但是一段逻辑你根本不知道在哪一层。当然也可能是逻辑本身就揉成一坨,也不容易找到想要的东西。
快速的发现相关逻辑,可以减少很多维护成本。
当然,有些架构有学习成本,但是掌握之后,能够满足这个要求,我觉得也可以算是好的架构。
2.2 Web开发,可扩展性大于可复用性
根据我一些有限的经验看来,在互联网领域,复用的需求,其实并不如产品需求变更来的迫切。水平分层很大的动机是复用,但是往往内部的复用程度比较有限。而面对需求的变化,水平分层基本上从上到下都进行修改。而合理的垂直拆分可以只修改一个地方,这也是所谓的开闭原则了。
【关于投稿】
如果大家有原创好文投稿,请直接给公号发送留言。
① 留言格式:
【投稿】+《 文章标题》+ 文章链接
② 示例:
【投稿】《不要自称是程序员,我十多年的 IT 职场总结》:http://blog.jobbole.com/94148/
③ 最后请附上您的个人简介哈~
领取专属 10元无门槛券
私享最新 技术干货