单一职责原则

单一职责原则

一个类只负责完成一个职责或者功能。不要设计大而全的类,要设计粒度小、功能单一的类。单一职责原则是为了实现代码高内聚、低耦合,提高代码的复用性、可读性、可维护性。

如何判断类的职责是否足够单一?

不同的应用场景、不同阶段的需求背景、不同的业务层面,对同一个类的职责是否单一,可能会有不同的判定结果。实际上,一些侧面的判断指标更具有指导意义和可执行性,比如,出现下面这些情况就有可能说明这类的设计不满足单一职责原则:

  • 类中的代码行数、函数或者属性过多;
  • 类依赖的其他类过多,或者依赖类的其他类过多;
  • 私有方法过多;
  • 比较难给类起一个合适的名字;
  • 类中大量的方法都是集中操作类中的某几个属性。

优势

  1. 类的复杂性降低,实现什么职责都有清晰明确的定义
  2. 可读性提高,复杂性降低,那当然可读性提高了
  3. 可维护性提高,可读性提高,那当然更容易维护了
  4. 变更引起的风险降低,变更是必不可少的,如果接口的单一职责做得好,一个接口修改只对相应的实现类有影响,对其他的接口无影响,这对系统的扩展性、维护性都有非常大的帮助

总结

单一职责原则通过避免设计大而全的类,避免将不相关的功能耦合在一起,来提高类的内聚性。同时,类职责单一,类依赖的和被依赖的其他类也会变少,减少了代码的耦合性,以此来实现代码的高内聚、低耦合。但是,如果拆分得过细,实际上会适得其反,反倒会降低内聚性,也会影响代码的可维护性。

例子

  • 假设我们要做一个用户修改名字以及修改密码的功能
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class UserModifyImpl : UserModify {
override fun modifyUserPassword(user: User, password: String) {
user.password = password
}

override fun modifyUserName(user: User, name: String) {
user.name = name
}

}

interface UserModify {
/**
* 修改用户密码
*/
fun modifyUserPassword(user: User, password: String)

/**
* 修改用户名称
*/
fun modifyUserName(user: User, name: String)
}

data class User(
var password: String,
var name: String,
)
  • 假设我们让小明去倒垃圾,小红去买菜,小红回来后再叫小红去洗碗
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class XiaoMing : TakeOutTheTrash {
override fun doPourGarbage() {
println("小明 倒垃圾")
}
}

class XiaoHong : GroceryShopping, WashingUp {
override fun doShopping() {
println("小红 买菜")
}

override fun doWashingUp() {
println("小红 洗碗")
}
}

interface GroceryShopping {
/**
* 买菜
*/
fun doShopping()
}

interface TakeOutTheTrash {
/**
* 倒垃圾
*/
fun doPourGarbage()
}

interface WashingUp {
/**
* 洗碗
*/
fun doWashingUp()
}
  • 我们要实现一个用户注册、登录、注销操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* 用户注册
*/
class UserRegister{
fun doRegister(user: User){}
}
/**
* 用户登录
*/
class UserLogin{
fun doLogin(user: User){}
}

/**
* 用户注销登录
*/
class UserLogout{
fun doLogout(user: User){}
}

data class User(
var password: String,
var name: String,
)