重构原则:
我们重构代码的原则很简单,就是我往让代码保持:1、清晰2、简单3、可扩展。
重构方法:
1、 提取子函数
2、 上移至父类
3、 下移至子类
4、 封装固定的调用逻辑
5、 使用泛型去除重复逻辑
6、 使用对象避免过多的参数
7、 转移函数
8、 将类型码转换为状态模式
9、 什么也不做的对象——NullNObject模式
10、 将大类分解为小类
提取子类:
提取子函数的目的是为了保证在主函数中能够有一个简单、清晰的逻辑,保证主干看着清晰明了,不要有太多的旁枝末节的操作。
为此,我们需要将主干中的函数按照特定的功能提取到子类当中。
Eg:
private 起床上班{
起床、穿衣服、叠被子、洗脸、刷牙、吃早点、出门,赶公交、到公司、打卡、进公司
}
这样看主干其实很繁琐。我们可以把一些方法进行封装
private 起床吃饭{
起床、穿衣服、叠被子、洗脸、刷牙、吃早点
}
private 出行{
出门,赶公交
}
private 到公司打卡{
到公司、打卡、进公司
}
最后的主干就是:
private 起床上班{
起床吃饭、出行、到公司打卡
}
上移函数到父类:
在写子类的时候,突然发现有多个子类同时都用到了某个方法,或是某一段方法,或是某一类相同的动作。
对此,我们就可以考虑把这段代码,或者这一类动作封装到父类当中。
下移函数到子类:
在多个子类中都不需要父类的某一功能,该功能强加给了子类,子类和父类便多了一层耦合。那么我们可以把那几个功能提取出来,建一个新类。
Eg:
Private 交通工具{
启动、停车、加速、开门、关门
}
但是单车或是电动车就没有开门关门。所以我们就可以:
Private 交通工具{
启动、停车、加速
}
private 有门的车extends{
开门、关门
}
这样就将(开门、关门)下移到了一个子类当中。
封装固定的逻辑:
当有一套流程执行过程固定的时候,我们可以把这套逻辑封装成一个方法,也就是将多个流程封装到一个流程中。
Eg:
Private 开车{
开门、上车、关门、启动、加速、转弯,停车
}
这里开门、上车、关门这三个流程是固定的,所以我们乐意把它们提取到一个流程中
private 开车准备{
开门,上车,关门
}
使用泛型去除重复逻辑:
在处理多类对象时候,处理方法都很一致,而且处理流程和类型无关,为了简化处理流程,我们可以使用泛型来减少函数的量。
这类处理一般都是用作数据预处理然后再传递。因为不知道类型,所以无法对数据本身进行处理。
Eg:
Private classSimpleArrayList<T>{
Private T[] dataset;
Public SimpleArrayList(int size){
dataSet= (T[]) new Object[size]
}
public T get(int position){
returndataSet(position)
}
}
使用对象避免过多的参数:
在一个函数中需要传入多参数的时候的时候,我们可以将这些参数封装为一个对象属性,然后直接传递对象就好了。
Eg:
Private showRecommendation(title ,content, pic, writer, sail){
…
}
这里传递参数有点多,封装一下就好传递了
class ShareData{
title ,content, pic, writer, sail
}
转移函数:
在一个类中的方法,太依赖另外一各类中的诸多属性,我们可以考虑把这个方法放到另外一个类中。
Eg:
Class 班级{
学生id集合;
}
Class 同学{
同学id;
Private同学是否在某个班级{
For(遍历班级.学生id){
遍历班级.学生id ==同学id
返回true
}
}
}
同学这里比较依赖班级的学生id集合这个属性。与其增加耦合不如将这个方法就放在班级中从而减少耦合。
Class 班级{
学生id集合;
Private 同学是否在某个班级(同学){
For(遍历班级.学生id){
遍历班级.学生id ==同学.id
返回true
}
}
}
Class 同学{
同学id;
}
将类型码转为状态模式:
这个就是说switch或者if else并不是解决多状态的最后方法,最好还是用设计模式里面的状态模式去解决。这个去看设计模式就好了。
什么也不做的对象——NullNObject模式
也就是为了避免空指针异常而出现的模式。
这个去看NullObject模式就好了
将大类分解为小类
让每个类符合单一职责原则。保证每个类功能明确。