6 设计模式原则之单一职责原则
一、单一职责原则
1.定义
一个类应该只有一个职责,或者说,一个类应该仅仅做一件事情。
这样设计的好处是:
- 可维护性:当类的职责单一时,修改它时不会影响到其他的功能。
- 可扩展性:因为职责清晰,扩展功能时可以避免对现有功能的干扰。
- 高内聚:一个类中的方法和属性紧密关联,更容易理解和管理。
2.代码举例
为了说明单一职责原则,首先我们可以写一个违反单一职责原则的例子,然后再重构它。
// 违背单一职责原则的例子
public class Employee {
private String name;
private int age;
// 构造器和getter/setter省略
// 处理员工的工作
public void work() {
System.out.println(name + " is working");
}
// 处理员工的工资支付
public void calculateSalary() {
System.out.println("Calculating salary for " + name);
}
// 生成员工报告
public void generateReport() {
System.out.println("Generating report for " + name);
}
// 保存员工信息
public void save() {
System.out.println("Saving employee " + name + " to database");
}
}
上面的 Employee
类显然违反了单一职责原则,因为它负责了多个责任:
- 工作职责:执行员工工作
work()
。 - 工资计算职责:计算工资
calculateSalary()
。 - 报告生成职责:生成报告
generateReport()
。 - 持久化职责:保存员工数据
save()
。
一个类应该只有一个变化的原因,而这里 Employee
类有四个不同的职责。如果未来需要改变报告生成的逻辑或工资计算的逻辑,我们就需要修改 Employee
类,导致高耦合和低内聚。
3.代码重构
我们将 Employee
类重构为多个类,每个类只关注一个责任。
// 员工类,只关注员工的基本信息
public class Employee {
private String name;
private int age;
// 构造器和getter/setter省略
}
// 工作者类,负责员工的工作职责
public class Worker {
public void work(Employee employee) {
System.out.println(employee.getName() + " is working");
}
}
// 工资计算类,负责计算员工的工资
public class SalaryCalculator {
public void calculateSalary(Employee employee) {
System.out.println("Calculating salary for " + employee.getName());
}
}
// 报告生成类,负责生成员工报告
public class ReportGenerator {
public void generateReport(Employee employee) {
System.out.println("Generating report for " + employee.getName());
}
}
// 数据持久化类,负责保存员工信息
public class EmployeeRepository {
public void save(Employee employee) {
System.out.println("Saving employee " + employee.getName() + " to database");
}
}
public class Client {
public static void main(String[] args) {
// 创建员工对象
Employee employee = new Employee("John", 30);
// 执行工作
Worker worker = new Worker();
worker.work(employee);
// 计算工资
SalaryCalculator salaryCalculator = new SalaryCalculator();
salaryCalculator.calculateSalary(employee);
// 生成报告
ReportGenerator reportGenerator = new ReportGenerator();
reportGenerator.generateReport(employee);
// 保存员工信息
EmployeeRepository repository = new EmployeeRepository();
repository.save(employee);
}
}
-
每个类的职责单一:
Employee
类只包含员工的基本信息。Worker
类只负责执行工作。SalaryCalculator
只负责计算工资。ReportGenerator
只负责生成报告。EmployeeRepository
只负责保存员工信息。
-
低耦合:
- 每个类的职责明确,类与类之间的关系通过接口和调用传递数据来实现。这样修改某一类的功能时,不会影响其他类。
-
高内聚:
- 每个类的功能清晰,内部方法和属性紧密相关。类的可读性和可维护性更高。
-
易于扩展:
- 如果以后需要修改工资计算的逻辑或增加新的职责(比如处理考勤等),我们可以直接扩展相关的类,而不会破坏现有的代码结构。
4.总结
通过这个重构,我们可以看到单一职责原则的应用带来了以下好处:
- 高内聚,低耦合:每个类的职责单一,类之间的耦合度降低,修改某一功能时,不会影响其他功能。
- 易于维护和扩展:如果以后需要增加新功能(例如处理员工考勤),我们只需要新增一个类,现有功能不需要修改,代码的可扩展性增强。
- 清晰的责任划分:每个类的责任明确,代码结构清晰,方便理解和协作开发。