1.0 、概述

There should never be more than one reason for a class to change。
(应该有且只有一个类引起类的变更)

单一职责原则的英文名称是Single Responsibility Principle,简称是 _
SRP**_。这个设计原则备受争议,只要你想和别人争执、怄气或者是吵架,这个原则是屡试不爽的。

单一职责是最简单的设计模式,也是最难的设计模式,说之简单是因为这几个字非常好理解,每个类只承担一个责任;说之最难是因为每个类所承担的责任均是不可定性分析的,这需要根据实际的开发环境和开发的要求来衡量。如同第二个电话的实例,假如业务中要求电话仅仅只有三个简单的功能,并不需要对其进一步处理,实现图1-3的设计方式也没大的问题,但是这显然是未被SRP原则的,所以SRP的也是因环境而异,因项目而异。

1.1 、 用户信息的逻辑

在经典的RBAC (Role-Base Access Controller ,基于角色的访问权限控制), 通过分配用户的角色来达到权限的赋予和解除,在这个案例中,笔者以用户的信息修改为源头,来了解一下什么是合理的SRP。

1、单一职责原则(SRP) - 图1 图1-1

我们在工作中常常会写出上面的代码,这符合我们的日常开发的流程,创建一个UserInfo 对象,实现对应的服务方法,这样的写法在实际的开发过程中非常常见,但是我们来分析下,UserInfoService 总共承担的那些责任

  • 更新用户信息
  • 获取用户信息

显然这样的实现是存在问题的,根据单一职责的原则,UserInfoService 承担了两个责任,这显然违背了单一职责的原则。

1、单一职责原则(SRP) - 图2 图1-2

1.2 、拨打电话的逻辑

我们再来看看下面这个例子是否好理解。电话这玩意,是现代人都离不了,电话通话的时候有4个过程发生:拨号、通话、回应、挂机,那我们写一个接口,其类图如图1-3所示。

1、单一职责原则(SRP) - 图3 图1-3

根据分析,显然PhoneService 承担了两个职责: 对电话状态的修改,如拨打电话和挂断电话 & 电话数据的传输。我们思考下面两个问题

  1. 当电话的传输协议出现问题的时候,这个类会被修改吗?
  2. 当PhoneService新增网络服务的时候回对这个类进行修改吗?

显然答案均为是,这就违反了,开头说的:有且仅有一个原因导致某个类的修改, 根据这样,我们可以修改为以下的代码逻辑:

1、单一职责原则(SRP) - 图4 图1-4