不要存在多于一个导致类变更的原因.
举个简单的例子, 我定义了一个接口AB, 定义了两个方法 methodA 和methodB
public interface AB {
void methodA(String a);
void methodB(String b);
}
这时我需要有一个方法需要实现接口A,但是因为AB两个接口是在一起的,所以这里我给B一个空实现,代码如下:
public class AImpl1 implements AB{
@Override
public void methodA(String a) {
System.out.println(a);
}
@Override
public void methodB(String b) {
return;
}
}
这时需求变化,我不得不对methodB做一些修改,比如增加一个参数, 此时AImpl1这个类明明并不关心methodB却因为AB接口的更改而不得不随之改动.
这时我们需要修改设计, 将AB接口拆成两个独立的接口
public interface A {
void methodA(String a);
}
public interface B {
void methodA(String a);
}
这时A的实现类只需实现A接口即可
public class AImpl2 implements A{
@Override
public void methodA(String a){
System.out.println(a);
}
}
此时如果B接口有改动,那么只需修改实现了B接口的类即可,AImpl2 类不受影响, 即只存在一个导致类AImpl2 更改的原因
类的单一职责, 贴个别人的代码示例帮助理解
https://blog.csdn.net/zhengzhb/article/details/7278174
另外做一点补充, 单一职责原理不仅仅是一个类或接口应该承担尽量少的职责, 函数也是, 我们在工作中通常会对一些业务逻辑做一些封装来让代码的逻辑看起来清晰一点, 当封装到函数中业务逻辑发生变化时, 比如需要对一些特殊的值或场景做一些额外的处理, 比较简便的做法是直接 if else即可, 但更推荐遵循单一职责原理, 把不同的业务逻辑封装到不同的方法中, 这样代码会更清晰, 代码也更易维护一些
比如我们经常遇到这种情况, 参数中传入一个boolean值根据是否为真执行不同的逻辑, 这时代码的可读性就不太好,从方法名无法明确知道方法的职责, 因为方法名根据不同的逻辑承担了两种责任
public void doSth(Object obj, boolean flag){
if(flag){
// TODO ...
}else {
// TODO ...
}
}
建议改写为
public void doSth1(Object obj){
// TODO ...
}
public void doSth2(Object obj){
// TODO ...
}
这样每个函数承担各自的职责,逻辑判断交给上层, 这样逻辑会更加清晰, 如果将来逻辑发生变更我们只需要更改变更的那个函数的即可,不会对另一个函数的代码造成影响
优点
- 降低类的复杂度,提高可读性
- 提高系统可维护性,降低变更引起的风险