什么是单一职责原则
单一职责原则指一个类应当只负责一件事情。
带来了哪些好处
单一职责原则本质上是在提高类的内聚性。带来的好处有
- 结构更清晰,降低了类的复杂度
- 提高了代码的可读性
- 提高了代码的可维护性
- 降低了“代码变更”影响的范围
如何用好单一职责
结合业务去审视类的定义,使类与业务实体相对应。
举例
该场景根据笔者看到的真实案例改写而成。
场景描述:一年级做了一次语文模拟考试。现在有如下三个需求:
- 找出得100分的学生
- 找出分数在【90,100】的学生
- 找出分数是90、96或100的学生
代码实现
class Student {
private grade;
public Student(int grade) {
this.grade = grade;
}
public getGrade() {
return grade;
}
}
原先的代码实现是
class Filter {
private int[] filterGrades;
public RangeFilter(int[] grades)
this.filterGrades = grades;
}
List<Student> filter(List<Student> students) {
List<Student> result_students = new ArrayList<Student>();
for (int =0; i < students.size(); i++) {
Student student = students.get(i);
if (this.filterGrades.length = 1) {
//做单一分数过滤(例如100分)
} else if(this.filterGrades.length = 2) {
//做分数范围过滤,如【90,100】
} else if(this.filterGrades.length > 2) {
//做分数列表过滤,如(90,96,100)
}
}
}
}
}
说明:为了简化代码便于说明问题,具体过滤的代码没有写出
可以看到,以上代码将三种过滤方式融合在一个类Filter当中,表面看功能很强大,但实际上有如下不足:
- 代码复杂,需要根据filterGrades的长度来对到底做哪种过滤进行区分。实际上还引入了bug,因为当filterGrades为2时,有可能是范围过滤(场景描述中的第2种过滤),也有可能是两个分数的过滤(第3种过滤)。比如当filterGrades是[90,100]时,既有可能是要找到90到100分的学生,也有可能是要找到90分或100分的学生。
- 可读性差
- 可维护性差
- 当对Filter代码做修改时极有可能会对三种过滤都有波及
当把代码改为如下形式之后就清晰多了
interface Filter {
List<Student> filter(List<Student> students);
}
class ValueFilter implements Filter {
private int filterGrade;
public ValueFilter(int grade)
this.filterGrade = grade;
}
List<Student> filter(List<Student> students) {
//做单一分数过滤(例如100分)
}
}
class RangeFilter implements Filter {
private int minGrade;
private int maxGrade;
public RangeFilter(int minGrade, int maxGrade)
this.minGrade = minGrade;
this.minGrade = maxGrade;
}
List<Student> filter(List<Student> students) {
//做分数范围过滤,如【90,100】
}
class CollectionFilter implements Filter {
private int[] filterGrades;
public CollectionFilter(int[] grades)
this.filterGrades = grades;
}
List<Student> filter(List<Student> students)
//做分数列表过滤,如(90,96,100)
}
}