代码重构的几点原则:
- 存在重复的代码,可以考虑把重复的代码提到一个公共方法中。
- 一个方法的代码太长,越长的代码越不好维护,这种情况可以把方法按照功能点切分成小的方法,while,if等都是我们切分的依据,可以把while里面的提到一个独立的方法中。
- 参数列表过长,参数列表过长不好调用和维护,很难无法理解参数的意思,这时可以考虑把参数封装成对 象传进去,或者直接传入已有的对象。
- 发散式变化,如果出现了修改一个地方同时要修改其他几个地方,可以考虑把变化的封装起来,这样下次修改只需要修改封装的变化就好了。
- 少用switch case.对于面向对象的语言,使用switch,case意味着每次添加了新的东西就要修改case,这不服我们的以点切入的原则,这时可以考虑使用多态
- 子类不用重写父类的大量方法,这时可以考虑在中间加入抽象层,子类直接继承抽象层。
方法的命名
- 类名应该用名称
- 方法名应该用动词
- 避免误导(0和O,数字1和字母l)
- 使用可以读出来的名称,能概况用途的词
- 多使用专业词比如:jobQuene,Vistor
代码重构的方式
局部变量让代码难以维护,尽量把局部变量替换为方法。
double getPrice(){
double basePrice=_quntity*_itemPrice
if(basePrice>1000) return basePrice*0.95
else return basePrice*0.98
}
改变后
double basePrice(){
return _quntity*_itemPrice;
}
private double discountFactor(){
if(basePrice()>1000) return 0.95;
else return 0.98;
}
double getPrice(){
return basePrice()*discountFactor();
}
可见改变成方法更加方便了变量的共享,而临时变量只在当前方法有限
引入解释型变量
将复杂的表达式放在的结果放在临时变量中并取一个很好理解的变量名,有助于代码的阅读,在复杂的算法中可以将算法的步骤保存在临时变量中,有助于算法的理解,但是我一般更偏向于把算法的步骤提炼成方法,如果提炼成方法难度较大才考虑提炼成变量。
改变前
if((platform.toUpperCase().indexOf("MAC")>-1)&&(brower.toUpperCase().indexOf("IE")>-1)&&wasInitialize()&&resize()>)){
//do something
}
改变后
final boolean isMacOs=platform.toUpperCase.indexOf("MAC")>-1
fianl boolean isIEBrower=platform.toUpperCase.indexOf("IE")>-1
fianl boolean wasResized=resize>0;
if(isMacOs&&isIEBrower&&wasInitialize()&&wasResized){
//do something
}
分解临时变量
如果你的临时变量被赋值超过一次,它既不是循环又不是用于收集计算结果(通过整个函数的运算将计算的结果收集起来),
请使用多个临时变量。一个临时变量一般只需要承担一个责任,如果承担多个责任将导致代码难以维护。
移除对基本类型参数的赋值
原因:Java严格遵守按值传递,对参数的任何修改都不会对调用端造成任何影响,如果你对传入的对象参数赋值表示使她引用另一个对象,而且传入的参数只表示传入的值不做其他责任这样代码的可能性更强
改变前
int discount(int inputVal,int qunitity,int yearToDate){
if(inputVal>50) inputVal-=2;
}
改变后
int discount(int inputVal,int qunitity,int yearToDate){
int result=inputVal;
if(result>50) result-=2;
}
有2中情况可以直接对传入的参数进行修改1:传入的是对象,2:传入的参数要被return 回去。
替换算法
把算法替换为更加清晰的算法
改动前:
String foundPerson(String[] people){
if(int i=0;i<people.length;i++){
if(people[i].equals("Don")){
return "Don";
}
if(people[i].equals("John")){
return "John";
}
if(people[i].equals("Kent")){
return "Kent";
}
}
return "";
}
改动后
String foundPerson(String[] people){
List candidates=Arrays.asList(new String[]{"Don","John","Kent"});
for(int i=0;i<people.length;i++){
if(candidates.contains(people[i]){
return people[i];
}
}
return "";
}