设计原则·单一职责原则
单一职责字面意思就是每个类有着他们专属的责任,这样可以在更新某一个类逻辑的时候,不会影响到其他的逻辑。
单一职责原则中有个相关名词:职责扩散。
所谓职责扩散,就是因为某种原因,职责P被分化为粒度更细的职责P1和P2。
在职责扩散在控制范围内可以适当的根据需要以一个类来背负多个责任。
但是必须要在职责扩散失控之前重构代码。
语言类
public class Language {
public void speakLanguage(String name){
System.out.println(name + "讲汉语");
}
}
人类
public static void main(String[] args) {
Language language = new Language();
language.speakLanguage("北京人");
language.speakLanguage("南京人");
}
北京人讲汉语
南京人讲汉语
显然是不对的,因为别的地方的人不是讲汉语。于是进行修改:
语言类
public class Language {
public void speakLanguage(String name){
if("韩国人".equals(name)){
System.out.println(name + "讲韩语");
return;
}
System.out.println(name + "讲汉语");
}
}
人类
public static void main(String[] args) {
Language language = new Language();
language.speakLanguage("北京人");
language.speakLanguage("南京人");
language.speakLanguage("韩国人");
}
北京人讲汉语
南京人讲汉语
韩国人讲韩语
这样修改看结果是没有问题的,但是如果新添加几种人类,那就还要加if判断,隐患很大。
于是根据单一职责原则,将语言类一分为二:
语言类
public class LanguageCN {
public void speakLanguage(String name){
System.out.println(name + "讲汉语");
}
}
public class LanguageKO {
public void speakLanguage(String name){
System.out.println(name + "讲韩语");
}
}
人类
public static void main(String[] args) {
LanguageCN language = new LanguageCN();
language.speakLanguage("北京人");
language.speakLanguage("南京人");
LanguageKO languageKO = new LanguageKO();
languageKO.speakLanguage("韩国人");
}
北京人讲汉语
南京人讲汉语
韩国人讲韩语
这样写结果也没有问题,但是修改的地方比较大,在职责扩散可控的范围内我们可以这样写,虽然违背了职责单一原则:
语言类
public class Language {
public void LanguageCN(String name){
System.out.println(name + "讲汉语");
}
public void LanguageKO(String name){
System.out.println(name + "讲韩语");
}
}
人类
public static void main(String[] args) {
Language language = new Language();
language.LanguageCN("北京人");
language.LanguageCN("南京人");
language.LanguageKO("韩国人");
}
北京人讲汉语
南京人讲汉语
韩国人讲韩语
这种写法在方法的层面上是符合单一职责原则的,因为他的扩展没有改动原有的方法,只是在原有的方法基础上扩展了新的方法。
不过这个例子是极其简单的,在现实业务中是要复杂很多的,在复杂的逻辑业务中发生职责扩散的时候还是根据单一职责的原则来重构比较好。