第三章 函数
1.函数要短小
20封顶最佳,尽可能短小。
2.只做一件事
职责单一原则,一个函数只做一件事情,是否只做了一件事的判断依据是通过抽象层级看来,只做一个抽象层级上的事情。
3.每个函数一个抽象层级
先做tasking,再开始实现功能,编码之初就应该将抽象层级划分好。
4.switch
switch语句一般会冗长,所以可以通过工厂模式将其底层隐藏在工厂类中供外界使用。
public interface OperationTypeFactory {
public OperationType.Type makeOperationTypeByOrderStatus(OrderStatus.Type type);
}
public class OperationTypeFactoryImpl implements OperationTypeFactory{
@Override
public OperationType.Type makeOperationTypeByOrderStatus(OrderStatus.Type type) {
switch (type){
case Submitted:
return OperationType.Type.Submitted;
case Audited:
return OperationType.Type.Audited;
case Paid:
return OperationType.Type.Paid;
case Closed:
return OperationType.Type.Close;
case Cancelled:
return OperationType.Type.Cancelled;
case ConfirmingPayment:
return OperationType.Type.OfflinePaidConfirmSuccess;
case OfflinePaidNotConfirmed:
return OperationType.Type.OfflinePaidConfirmFail;
case OfflinePaidAwaitingConfirm:
return OperationType.Type.FillInOfflineInfo;
case OrderTracking:
return OperationType.Type.Transporting;
case WaitForPay:
return OperationType.Type.WaitForPayment;
case Delivered:
return OperationType.Type.Delivered;
default:
throw new IllegalStateException("Unexpected value: " + type);
}
}
}
5.使用描述性的函数名
不要害怕花长时间为函数取名字,一个好的表意的名字,可以让他人和自己在下次阅读代码时更好的领会当前代码的含义。
6.函数参数
函数参数尽量少,0个最好,1个次之,非必要绝对不用三个。
7.输入参数
避免输出参数,尽量使用输入参数。
int func(int a , int *p)
{
*p = a +10;
return 0;
}
int main()
{
int x , y ;
x = 10;
func(x,&y);
printf("x = %d \n", x);
printf("y = %d \n", y);
return 0;
}
运行结果:
x = 10
y = 20
结论:
(1) func函数中a是输入型参数,p是输出型参数。
(2)形参的传值调用是输入型参数。传址调用即有可能是输出型参数,也有可能是输入型参数。作为输入型参数使用时,一般会加入const关键字,表明是只读,不能修改。
1、输入型参数是指这个参数的值已知,由外面传给函数里使用.
2、输出型参数是指这个参数的值未知,要通过函数传出来.
8.分隔指令与询问参数
一个函数要么做什么事,要么回答什么事,函数应该修改某对象的状态或者返回对象的信息,不能两者都包含,否则会很混乱。
9.使用异常代替返回错误码
在发生错误时避免通过返回码的方式处理,直接使用try catch捕获后处理对应的异常信息。
一个函数只做一件事,而错误处理就是一件事。
将try catch结构的代码抽离出来,然后形成单独的函数直接调用。错误处理函数不应该直接存在于正常流程当中。
10.避免重复的代码块
11.重构函数
在函数功能完成之后,再通过重构的手法去除代码中的问题,例如过长的参数列表,重复的代码块等。