更多文章请参见:我的blog
1. 问题域定义
这个问题往大的说是业务治理问题,往小了说是代码分拆。
我的建议是自顶向下的思考,自顶向下的思考方式一方面全局的看一个问题,能给出一个问题最优解,另一方面因为只有这样才有成长,才能在下次遇到类似问题时解决问题。
考虑清楚为什么会形成超大的类?
可以通过哪些方法对业务进行拆分,以达到拆分的效果?
拆分完成之后怎么判断拆分的是否合理?
2. 问题分析
2.1 怎么形成的超大类
刚开始编写这个文件的时候,我相信作者肯定是已经想过了这个类要负责什么,哪些业务应该在这个类中,这个类与上下游的关系是什么样的。但是最初在第一次业务变更时有一点不太应该在本类中加进来的业务代码,但跟本类有这强联系的代码就直接加。之后总有类似的事情发生,总有不是强相关,但又有关系的代码加入进来。导致代码随着业务不断地变化与调整,而逐渐的陷入混乱。
所以,不必担心业务代码不会增长,它的增长是不受控制的。就像物理学中的熵增定律一样,在一个封闭系统中,如果没有外部做功,它就会逐渐陷入混乱。
2.2 用什么进行业务治理?
业务代码的增长,随后陷入混乱是必然的,这件事是不是让人感到这个问题就无解了。因为不管改多少遍都会陷入混乱,在一个无法解决的问题上人们总是会感觉到无力,从而丧失解决从根本上解决问题的力量。
不要使用上帝类,在DDD中有上帝类的概念。上帝类就是在一个类中解决所有的问题,可以看到MVC模式中的Service就是上帝类的完美代表。所以,不要只用一种模式解决所有的问题。这里给出的都是思考的过程以及方式来解决问题。所以可能会感觉到泛泛之谈。
这里主要思想是DDD,但是经过了一些变形:明确服务边界,定义服务内容,阐述服务关系。具体到代码拆分上:
**从业务上划分包**:包中的业务是对于特定的业务实体的操作。
**定义包的边界**:包中的实体发生变化,应该以事件的方式通知其他关心的业务。而不是由本包解决所有的外部问题
**明确包与包之间的关系**:包中只负责本包该处理的业务,不负责其他业务实体的业务。例如:在下单之后,应该以事件的方式通知仓库,支付,物流等等去做该做的事情。而不是自己去做。
2.3 判断拆分的是否合理?
最简单的规则就是单一职责,拆分后的内容是否符合单一职责。然后就是扩展到SOLID规则。
3. 解决域展示
实际解决过也是一个不断演化的过程,接受代码会随着时间不断的变化才会接受这种解决方式。
第一阶段:facade模式
将facade类作为能力透出类,而拆分出的实际工作类作为业务功能类。例如:策略部署其实可以分为策略定义和策略的使用,就可以使用facade类向外暴露接口能力,然后策略定义一个类,测录使用一个类。
第二阶段:划分领域对象
进一步就是就是将拆分出的两个实现类再拆分为:工具类,服务类,外部事件处理类,领域事件类。从名字就可以知道它这些类的意义。
4. 总结
业务治理是长期工作,需要理解问题产生的原因才可以真正的解决问题。