为什么需要重构
- 维护困难
- 维护困难是由多方面因素所引起的,例如命名规则,处理过程,算法实现等
怎样实现
格式化
- 格式化的目的是为了能集中注意力,不至于因为糟糕的格式影响读代码的心情
去掉全局变量
- 因为是作为库进行发布的,如果作为全局变量很有可能和其他名称相冲突
- 解决的方法:
- 变量由外部传入,即整个处理过程对于外部调用方是完全可控的,没有内部的隐含输入
- 将内部的API使用static进行包含
- 将整个库放置到单独的命名空间中(这需要语言的支持)
审核库中对于资源的申请和释放
- 对于资源的把控是嵌入式程序员的必修课,所以见到malloc/new等就会自然的反应,free/delete呢?所以,一见到库中有大量的new而且见不到delete时,自己是不敢使用这个库的
double** J = new double*[6];
- 解决的方法
- 对于需要传回的资源,由外部传入空间,不允许在callee中进行资源的申请
- 善于使用栈上的空间,在新版的C类编译器中是可以支持可变数组的定义的,这样就省去了小空间从堆上分配的麻烦
double localRads[ angleCount ];
重新封装API
- 库中所定义的API的过程处理痕迹明显,所以面对巨大的数组,内心是崩溃的。诚然,使用这种内存布局的好处就是便于在ABI的层次进行兼容。
res.P1 = tempP[j][0];
res.P2 = tempP[j][1];
res.P3 = tempP[j][2];
res.P4 = tempP[j][3];
res.V1 = tempV[j][0];
res.V2 = tempV[j][1];
res.V3 = tempV[j][2];
- 解决的方法:
- 定义结构,利用语言的特性做一定的伪装(为了说明,我隐去了结构和变量名称),通过这种形式进行适配。
struct xxxXXX
{
union {
struct {
double x[4];
double xx[4];
double xxx;
};
double datas;
};
};
- 为了不污染全局空间,将库代码放置到命名空间再进行编译
namespace xxx
{
#include "outlib.cpp"
}
统一错误返回
- 对于可能失败的过程,定义统一的错误规则,
例如:0表示成功,其他表示错误。
为什么使用0?因为0太特殊了,不需要过多的说明和注释就能注意到
增加配置项
整理代码结构
- 简练整洁的代码赏心悦目
- 代码不仅是自己看的,后来人也会看。只有自己能看得懂的程序,不是优秀的程序。(如果自己都看不懂的程序,那就是垃圾)
添加注释
- 注释不再多,而在精
- 完美的程序不需要注释的,我们都是凡人,写不出完美的程序,所以注释是必不可少的
- 注释能自然地概括处理过程,便于从高层次上理解程序的实现
测试
- 测试前,需要多读几遍代码,逐个审阅各分支,循环等控制逻辑
- 重构的前提是能够正常工作
- 所以,需要进行单步的测试,确保正确性
网友评论