# 单一职责原则
定义:不要存在多于一个导致类变更的原因
理解:比如:一个类负责了 2 个功能,在修改功能 1 时,导致功能 2 发生了故障;两个功能在需求变更的时候都有可能导致类变更,那么该类存在两个导致类变更的原因
体现: 一个类、接口、方法只负责一项职责
优点:
- 降低类的复杂度
- 提高类的可读性
- 提高系统的可维护性
- 降低变更引起的风险
- 变更是必然的,单一职责原则遵循的好,可以降低变更引起的风险
- 单一职责也适用于模块化设计
开始coding
# 基本场景
场景:鸟的动作
public class Bird {
// 主要移动方式
public void mainMoveMode(String birdName) {
System.out.println(birdName + "用翅膀飞");
}
}
1
2
3
4
5
6
7
2
3
4
5
6
7
public class Test {
public static void main(String[] args) {
Bird bird = new Bird();
bird.mainMoveMode("大雁");
bird.mainMoveMode("鸵鸟");
}
}
1
2
3
4
5
6
7
2
3
4
5
6
7
大雁用翅膀飞
鸵鸟用翅膀飞
1
2
2
这里的结果就有问题了:鸵鸟主要移动方式是用脚走路。那么进行修改
public class Bird {
public void mainMoveMode(String birdName) {
if ("鸵鸟".equals(birdName)) {
System.out.println(birdName + "用脚走");
} else {
System.out.println(birdName + "用翅膀飞");
}
}
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
这个示例说实在的,我自己平时在开发的时候就经常这样做,这样做的原因有多种,比如
- 时间关系
- 感觉这个业务不怎么复杂,这样改动是最方便最快捷的
如果还有更多的不同移动方式的鸟类呢?这里的逻辑则会更多的判定。如果在一段很复杂的业务逻辑中,就很容易出错。这里就破坏了单一职责原则-降低变更引起的风险
# 类单一职责演示
把上面负责多职责的拆分成单一职责
// 会飞的鸟
public class FlyBird {
public void mainMoveMode(String birdName) {
System.out.println(birdName + "用翅膀飞");
}
}
1
2
3
4
5
6
2
3
4
5
6
// 用脚走的鸟
public class WalkBird {
public void mainMoveMode(String birdName) {
System.out.println(birdName + "用脚走");
}
}
1
2
3
4
5
6
2
3
4
5
6
由应用层来判定,什么鸟适合什么行走方式
FlyBird flyBird = new FlyBird();
flyBird.mainMoveMode("大雁");
WalkBird walkBird = new WalkBird();
walkBird.mainMoveMode("鸵鸟");
1
2
3
4
5
2
3
4
5
# 接口级别
public interface ICourse {
// ~----------- 课程信息
String getCourseName();
byte[] getCourseVideo();
// ~----------- 课程管理
/** 学习课程 */
void studyCourrse();
/** 退款这门课程 */
void refundCourse();
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
对于这个接口来说,有两个大的职责:获取课程信息和课程管理。
如果当课程被退掉的时候,这门课程的信息就获取不到了,也就是说 refundCourse 会影响获取课程信息相关的功能。
public interface ICourseContent {
// ~----------- 课程信息
String getCourseName();
byte[] getCourseVideo();
}
1
2
3
4
5
6
2
3
4
5
6
public interface ICourseManager {
// ~----------- 课程管理
/** 学习课程 */
void studyCourrse();
/** 退款这门课程 */
void refundCourse();
}
1
2
3
4
5
6
7
2
3
4
5
6
7
public class CourseImpl implements ICourseContent, ICourseManager {
@Override
public String getCourseName() {
return null;
}
@Override
public byte[] getCourseVideo() {
return new byte[0];
}
@Override
public void studyCourrse() {
}
@Override
public void refundCourse() {
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
由具体的实现选择来组合实现哪些功能(也可以只实现其中一个),
- 在接口级别上两个接口的职责是清晰的,隔离的。
- 复杂度也降低了,可读性也变高了
- 降低变更引起的风险,可维护性变高了
- 一个接口的修改不影响另一个接口的功能
# 方法级别
public void updateUserInfo(String userName, String address, boolean bool) {
if (bool) {
// 逻辑1
} else {
// 逻辑2
}
}
1
2
3
4
5
6
7
2
3
4
5
6
7
这种的逻辑,很明确的是两个功能逻辑,就可以完全拆分成两个方法来处理这不同的功能,而不是用一个标志来处理