该原则是针对类来说的,即一个类应该只负责一项职责。
如类T负责两个不同职责:职责P1,职责P2。当职责P1需求变更而改变T时,可能造成职责P2发生故障,所以需要将类T的粒度分解为T1、T2。
示例如下:
用一个类描述动物移动这个场景
/**
* 单一职责原则
*
* @author Sir丶雨轩
* @since 2021/12/23
*/
public class SingleResponsibilityPrinciple {
static class Animal {
public void move(String animal) {
System.out.println(animal + "在地上走");
}
}
public static void main(String[] args) {
Animal animal = new Animal();
animal.move("牛");
animal.move("羊");
animal.move("猪");
animal.move("鱼");
}
}
输出结果:
我们发现不是所有动物都是在地上走,比如鱼就是在水里游的,根据单一职责原则,我们将Animal类细分为陆生动物类和水生动物类,如下所示:
public class SingleResponsibilityPrinciple {
static class Terrestrial {
public void move(String animal) {
System.out.println(animal + "在地上走");
}
}
static class Aquatic {
public void move(String animal) {
System.out.println(animal + "在水里游");
}
}
public static void main(String[] args) {
Terrestrial terrestrial = new Terrestrial();
terrestrial.move("牛");
terrestrial.move("羊");
terrestrial.move("猪");
Aquatic aquatic = new Aquatic();
aquatic.move("鱼");
}
}
我们发现这样修改的花销很大,既要将原来的类分解,又要修改客户端。而直接修改Animal类虽然违背了单一职责原则,但花销小的多,如下所示:
public class SingleResponsibilityPrinciple {
static class Animal {
public void move(String animal) {
if ("鱼".equals(animal)) {
System.out.println(animal + "在水里游");
} else {
System.out.println(animal + "在地上走");
}
}
}
public static void main(String[] args) {
Animal animal = new Animal();
animal.move("牛");
animal.move("羊");
animal.move("猪");
animal.move("鱼");
}
}
可以看到,这种修改方式简单的多。但却存在隐患,一天需要将鱼分为淡水鱼,海水鱼,又需要修改Animal类的move方法。可能给“猪牛羊”等相关功能带来风险,这种修改直接在代码级别违背了单一职责原则,虽然修改起来最简单,但隐患最大。还有一种修改方式:
public class SingleResponsibilityPrinciple {
static class Animal {
public void move(String animal) {
System.out.println(animal + "在地上走");
}
public void move2(String animal) {
System.out.println(animal + "在水里游");
}
}
public static void main(String[] args) {
Animal animal = new Animal();
animal.move("牛");
animal.move("羊");
animal.move("猪");
animal.move2("鱼");
}
}
这种修改方式没有改动原来的方法,而是在类中新加了一个方法,这样虽然违背了单一职责原则,但在方法级别上却是符合单一职责原则的。那么在实际编程中,采用哪一种呢?我的原则是,只有逻辑足够简单,才可以在代码级违反单一职责原则;只有类中方法数量足够少,才可以在方法级别违反单一职责原则。
遵循单一职责的优点:
降低类的复杂度,一个类只负责一项职责。
提高类的可读性,可维护性
降低变更引起的风险。
评论区