短小
短小是函数的第一规则,20行封顶最佳。
每个函数最好只做一件事情,一目了然最佳!
代码块
if语句,else语句,while语句等等,其中代码块最好只有一行。
这一行最好就是函数调用语句。保持函数短小,调用的函数具有说明性的名称,能增加文档上的价值。
只做一件事
编写函数是为了把大一些的概念拆分成为另一抽象层上的一系列步骤。
一个函数一个抽象层次
抽象层次越高,具体信息越少,但是概括能力越强;反之,具体信息越丰富,结果越确定,但相应的概括能力越弱。
所以代码需要有层次感。
switch语句的麻烦
在抽象层次比较低的时候,很难避免使用switch语句。
public Money calculatePay(Employee e) throw InvalidEmployeeType{
switch (e.type){
case COMMITSSIONED:
return calculateCommissionedPay(e);
case HOURLY:
return calculateHourlyPay(e);
case SALARIED;
return calculateSalariedPay(e);
default:
throw new InvalidEmployeeType(e.type)
}
}
//判断雇员种类,分别进入不同的方法。
问题:
1.代码长了
2.出现新的雇员时还要增加代码。
3.违反单一权责原则。
4.违反开放闭合原则。
5.也许还有其他根据不同雇员执行的方法,这会造成代码重复。
修改:将switch隐藏到抽象工厂下
public abstract class Employee{
public abstract boolean isPayday();
public abstract Money calculatePay();
public abstract void deliverPay(Money pay);
}
----------------------------------------------------
public interface EmployeeFactory{
public Employee makeEmployee(EmployeeRecord r) throw InvalidEmployeeType;
}
----------------------------------------------------
public class EmployeeFactoryImpl implements EmployeeFactory{
public Employee makeEmployee(EmployeeRecord r) throw InvalidEmployeeType{
switch (r.type){
case COMMITSSIONED:
return new CommissionedEmployee(r);
case HOURLY:
return new HourlyEmployee(r);
case SALARIED;
return SalariedEmployee(r);
default:
throw new InvalidEmployeeType(r.type)
}
}
}
函数的参数
最理想的是0参数 ,其次是一,再就是二,应该尽量避免三个参数。
如果有三个或者三个以上的参数,最好封装成类了。
使用异常替代返回错误码
if(deletePage(page) == E_OK){
if(registry.deleteReference(page.name) == E_OK){
if(configKeys.deleteKey(page.name.makeKey())==E_OK){
logger.log("page deleted");
}else{
logger.log("configKey not deleted");
}
}
else{
logger.log("deleteReference from registry failed");
}
}else{
logger.log("deleted failed");
return E_ERROR;
}
-----------------另一方面---------------------------
try{
deletePage(page);
registry.deleteReference(page.name);
configKey.deleteKey(page.name.makeKey());
}catch(Exception e){
logger.log(e.getMessage());
}
参照《Clean Code》第三章