我们已经知道面向对象的目的是为了模块化。
这点请毋庸置疑,如果还不理解就想想过程编程,满眼的方法,以及方法调用,作为程序员的人看了,会疯掉。
TIP:高内聚、低耦合是模块化的状态。
因为一个人的心智消化系统只能够7+-2个事物。
抽象成对象,再“凝结”成模块化是最好的解决方法。
我们已经知道SRP是SOLID五大设计原则的“起始”原则,“终止”原则是OCP。
所以SRP是每个面向对象编程人员必须首要掌握的设计原则。
到了这里,你已经有两个知道:模块化、SRP。
把两者结合起来,想当然认为,SRP就是每个模块只做一件事,那就大错特错了。
微服务划分的时候,常常拿SRP作为指导原则,订单服务、促销服务、库存服务。它们都是SRP的。那么订单服务是只做一件事么,不仅要负责生成订单,还要负责提供别人查询订单,生成订单和查询订单,显然是不止一件事。
TIP:每个模块只做一件事,只是面向底层实现细节的设计原则,并不是SRP的全部。
进而,SRP有了更进一步的描述:任何一个模块都应该有且仅有一个被修改的原因。
到了这层描述的时候,SRP实际上已经是很“到位”了。在以往的过程中我们也经常拿这个描述来指导我们服务单一职责的设计。
要是,再往下,再往深,追一追呢。
“被修改的原因”,那么“谁”会来引起这个软件模块、这个服务、这个类被修改呢。
是的,软件被开发出来就是给用户、给人使用的,为了满足用户、人的需求,我们的模块会经常做出这样那样的修改。
那么这里的“谁”到底是“谁”呢。
是软件系统的利益相关者,是一个或者多个有共同需求的用户。
TIP:有些情况下,一个系统也是为另外一个系统负责的,不仅仅是人,了解即可,可以把人和系统都当成用户。
最终,SRP被描述为:任何一个软件模块都应该只对某一类行为者负责。
这里的行为者,就是软件利益的相关者,按照经济关系原理,没有利益就没有驱动,即便公益,也是造福多人的利益。
如果,你的软件模块对两类以上的行为者负责了,会怎么样呢。
TIP:记住软件模块,宏观上可以是服务,微观上可以是一个代码类、代码片段。
比如,我们有个服务提供了这样的功能,查询商家过去历史的订单,统计商家过去一段时间的操作活跃度。谁会跟查询历史订单更加利益紧密?肯定是商家。谁会跟商家的活跃度更加利益紧密?肯定是后台运营人员。
这里,就明显了这个服务对两类行为者负责了,商家和后台运营人员。
一周之内。
一天,商家向客服反映,他们需要查询两个月的历史订单,现在的功能仅支持一个月。
一天,后台运营人员找到产品经理,他们需要把商家的营业额度加上,以便于更进一步分析数据。
一天,商家又向客服反映,他们需要对查询后的订单列表进行下载,现在的功能不支持下载。
发现了没有。
对两种以上的行为者负责之后,你的软件模块,修改原因和修改频率,都受到了挑战。
商家和后台运营人员对软件修改的原因不同,因为他们跟软件之间的利益相关不同,修改原因肯定不同。同时,他们的行为所引起的软件修改频率也可能会不同,一周之内,商家的需求两次,后台运营人员的需求一次。
修改原因,修改频率,对于一个软件模块来讲,只有有一个因素经常发生变化,软件模块已经很”难受“了,更何况再加一个不同的修改频频,想想是不是”更难受“。
难受,最终还不都是程序员来承受了吗。
所以,程序员们要清晰的分辨出,一个软件模块现在服务了多少类行为者,深刻的认识出SRP的深层机理,才能够不”难受“,做一个自由的程序员。
对于一个程序员来讲,什么叫自由?
记住:需求自由。是程序员最大的自由。
编程世界最美好的样子,莫过于,程序员对着产品经理喊:我有代码,你有需求吗。
----END----