前面我们把23种设计模式聊了个遍。但这些设计模式中,我们有聊到一些设计原则,并以此作为佐证设计模式在解决问题上的优势。
在进一步深度分析设计模式之前,小二哥从这期开始,给大家分享下程序设计领域中的一些基本原则。
在面向对象编程和面向对象设计中,最为大家熟知的就是S.O.L.I.D原则
。
今天,我们重点讲其中的S:Single Responsibility Principle(SRP)
,也就是我们说的单一职责原则
。
一定要看到最后,教会你什么是“拆”字诀!
在面向对象的思想下,我们可以把属性和行为封装到一个单元里--我们称为类。
我们经常听到前辈们说,“把紧密相关的属性和行为封装在一起”。或许大家听过其他的说法。但有些说法是不准确的。
真正考虑封装一个类的依据时,这里的单一职责原则
就是其中之一。它规定一个类或模块应该只有一个引起变化的原因。换句话说,一个类或模块应该只负责完成一个单一的职责或功能。
我们自定义类时,如果只要做代码语法正确,那可以在一个类中掺杂各种各样的属性和行为。
但我们通常不像这样做。因为前辈们告诉我们,要注意“高内聚、低耦合”。
ps:“高内聚、低耦合”可不是什么原则哦,而是要达到的一种目的状态!
我们在写一些简单类的时候,往往会忽略单一职责原则
。因为,在我们看来它们足够简单和小巧。
比如,一个教师知识面非常广,既可以教语文,又可以教数学。于是,它就可以教授两门课程。这个怎么设计呢?
按照这个描述,我们可以快速的设计出这个类:
public class Teacher {
String name;
//省略setter/getter
public void teachChinese() {
System.out.println("教语文~");
}
public void teachMath() {
System.out.println("教数学~");
}
}
是不是很简单!
🆗,好了!现在教学改革了,不能再笼统的教学了。教语文的时候,需要分为听、说、读、写;教数学的时候,又分为算术、几何、微积分;
这下好了!我们怎么改上面的代码?是不是既要改 teachChinese() 方法,又要改 teachMath() 方法?
这时我们就有不止一个原因需要改动原来的代码。那说明上面的代码不满足单一职责原则。
怎么改?
这时,其他我们考虑的不应该是以老师(某某老师这个人)作为对象,而应该是教师这个职位作为对象。可以分为语文教师和数学教师两个对象。
语文教师复制语文相关的教学,包含听、说、读、写。
public class ChineseTeacher {
String name;
//省略setter/getter
public void teachListening() {
System.out.println("听~");
}
public void teachSpeaking() {
System.out.println("说~");
}
public void teachReading() {
System.out.println("读~");
}
public void teachWriting() {
System.out.println("写~");
}
}
数学教师复制数学相关的教学,包含算术、几何、微积分。
public class ChineseTeacher {
String name;
//省略setter/getter
public void teachArithmetic() {
System.out.println("算术~");
}
public void teachGeometry() {
System.out.println("几何~");
}
public void teachCalculus() {
System.out.println("微积分~");
}
}
语文教师和数学教师的职责是不一样的,需要分开!
如果不分开,仍旧把它们合在一个类中,从语法上讲一点毛病都没有!但它还是最开始那个简单的类吗?不是的!
在很多情况下,我们并不能一次性就按照这个原则把类写好! 尤其是才接触面向对象编程语言的小伙伴。
不要气馁!这很正常。连一些有经验的前辈,也会时不时的遇到这样的情况。重点是,我们要知道怎么去修改这样的代码。
关于通过单一职责原则
的优化、修改代码,小二哥告诉大家一个诀窍。一个字:“拆”
把“拆”字诀
用好,你就能慢慢掌握单一职责原则
啦~
ps:看看上面的代码,我们是不是通过“拆”来优化的呢?