定义
- 不要存在多余一个导致类变更的原因
- 一个类/接口/方法只负责一项职责
怎么理解?
尽量降低类间,方法间,接口间的耦合。
假设场景:(注意:这里说的任务是,独立开来是没有任何联系的)把多个任务 压到一个人身上,那样他会很累,而且,一个人,只能在同一时刻,做一件事,如果其中一件事没做好,就会影响没做完的事情的进度,或者因为心情不好,做后面的事情就变慢了,或者不想做了。(这么说,多个任务给一个人做,这些任务间,是相互影响的,耦合度高)。
那么如何摆脱这些影响呢?
我们可以只留一个任务给这个人做,其他任务分给其他人做,其他人也都是一个任务,那么不管这个任务有没有做完,做的多快,其他人的任务的快慢与这个人无关,互不影响。
我们需要注意:此解决方案,增加了很多人来执行任务,就相当于加了很多新的类/方法/接口,如果过度准寻,就会导致,人太多了,就相当于类/方法/接口过多,反而不好管理,查看。所以我们还是要根据业务来判断。
优点
对于一个类来说,降低类的复杂度(因为一个类需要做的东西变少了)、提高类的可读性(因为处理的东西少,所以容易知道这个类是干嘛的)、提高系统的可维护性(易读,耦合性低)、降低变更引起的风险(因为类/方法之间互不影响,所以增加新的东西也不会引起原先的东西变化)
实例
类的单一职责
Bird.java
public class Bird {
void walk(String name) {
System.out.print(name+"用翅膀飞");
}
}
Test.java
public class Test {
public static void main(String[] args) {
Bird bird = new Bird();
bird.walk("大雁");
bird.walk("鸵鸟");
}
}
输出结果:
大雁用翅膀飞
鸵鸟用翅膀飞
明显不符合,那么改成
Bird.java
public class Bird {
void walk(String name) {
if(name.equals("鸵鸟“) {
System.out.print(name+"脚走");
}else{
System.out.print(name+"用翅膀飞");
}
}
}
的确解决了bug,但是要是走路的鸟类还有很多很多中,用很多else if 加?一点也不现实, 一个类要做的事情太多了
所以,我们改成以下
WalkBird.java
public class Bird {
void walk(String name) {
System.out.print(name+"用脚走");
}
}
FlyBird.java
public class Bird {
void walk(String name) {
System.out.print(name+"用翅膀飞");
}
}
Test.java
public class Test {
public static void main(String[] args) {
FlyBird flybird = new FlyBird();
flybird.walk("大雁");
WalkBird walkBird = new WalkBird();
walkBird.walk("鸵鸟");
}
}
一个类,就处理一类职责,符合单一职责,也体现了好处
接口的单一职责
以一个网络课程接口为例
Course.java
public interface Course{
String getName();//课程名称
byte[] getVideo();//视频的字节数据
void startStudy();//学习
void refundCourse();//退课
}
假设场景: 调用refundCourse() 方法,退课之后, 按照这个接口来看, 课程名称就看不到了,这个是不应该的, 退课之后, 课程的名称还是应该存在的. 为什么会产生这个问题, 因为, 这个接口中的职责之间有关联性, refundCourse()会对 , getName() , getVideo()产生影响, 导致不能使用.
于是, 我们将职责拆分成, 获取课程内容的接口 和 管理课程的接口
CourseContent.java
public interface CourseContent {
String getName();//课程名称
byte[] getVideo();//视频的字节数据
}
CourseManage.java
public interface CourseManage {
void startStudy();//学习
void refundCourse();//退课
}
Course.java
public class Course implements CourseContent, CourseManage{
@Override
public String getName() {
return null;
}
@Override
public byte[] getVideo() {
return new byte[0];
}
@Override
public void startStudy() {
}
@Override
public void refundCourse() {
}
}
方法的单一职责
以一个学生类为例
Student.java
public class Student {
String name;
String ID;
String address;
String phone;
void setContent(String name, String ID, String address, String phone) {
//TODO 设置相应的属性
}
}
假设场景: 我想修改一个学生的名字, 那我得填所有的信息, 要是类的属性多, 那要填多少个参数, 而且,
于是, 我们将方法职责拆分
public class Student {
String name;
String ID;
String address;
String phone;
public void setName(String name) {
this.name = name;
}
public void setID(String ID) {
this.ID = ID;
}
public void setAddress(String address) {
this.address = address;
}
public void setPhone(String phone) {
this.phone = phone;
}
}
设置名字只要setName()填写一个参数就可以, 这就是单一职责的好处
再提一次优点
对于一个类来说,降低类的复杂度(因为一个类需要做的东西变少了)、提高类的可读性(因为处理的东西少,所以容易知道这个类是干嘛的)、提高系统的可维护性(易读,耦合性低)、降低变更引起的风险(因为类/方法之间互不影响,所以增加新的东西也不会引起原先的东西变化)