SRP:单一职责原则

SRP一般被误解为:每个模块都应该只做一件事。在《大话设计模式》中解释为:就一个类而言,应该有且仅有一个引起它变化的原因。在现实环境中,软件系统为了满足用户和所有者的需求,必然要经常做出这样或那样的改变。而该系统的用户或者所有者就是该设计原则的所指出“被修改的原因”。在软件中我们可以把一个或多个用户归为一类-----一个或多个有共同需求的人。所以SRP最终可以描述为:任何一个软件模块都应该只对某一类行为负责。代码与数据就是靠着与某一类行为者的相关性被组合在一起的。

示例

SRP:单一职责原则_第1张图片
Employee.png

上图是某个工资管理程序中的Employee类有三个函数calculatePay()、reportHours()和save()。这个类中的三个函数分别对应是三类非常不同的行为者。

  • calculatePay()有财务部门制定的,负责向CFO汇报
  • reportHours()人力资源部分制定并使用的,负责向COO汇报
  • save()有DBA制定的,负责向CTO汇报。
    这三个函数放在同一源代码文件中,这样实际就等于使三类行为者的行为耦合在了一起,这有可能会导致CFO团队的命令影响到COO团队所依赖的功能。calculatePay和reportHours函数使用同样的逻辑来计算正常工作时数,这时候需要抽取单独的算法workHours()来计算工作时长。
    这时候CFO团队需要修改正常工作时长的计算方法,但是HR团队则不需要修改。负责修改的程序员会注意到calculatePay函数调用了workHours,但是可能没有注意到reportHours函数也调用了。HR团队仍然在使用,这就会产生严重的后果。
    SRP强调这类代码一定要分开。如果一个类承担了的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者拟制这个类完成其他职责的能力。这种耦合会导致脆弱的设计,当变化时,设计会遭受到意想不到的破坏。

解决方案

  • 拆分
    设计三个类共同使用一个不包括函数的、十分简单的EmployeeData类,每个类只包含与之相关的函数代码,互相不可见,这样就不存在互相依赖的情况了。


    SRP:单一职责原则_第2张图片
    三个类.png
  • 外观模式


    SRP:单一职责原则_第3张图片
    外观设计.png

    这样设计,EmployeeFacade类所需要的代码量就很少了,它仅仅包含了初始化和调用三个具体实现类的函数。

你可能感兴趣的:(SRP:单一职责原则)