[代码评审1]代码评审
来源:p2p系统repayCalc.cs,本代码可能参考自线下系统
一 函数语言使用问题
1)Backdate日期类型改为DateTime,则可以不用字符串拼接
2)还款日计算错误(1个月 != 30天)
3)面向对象编程,而不是都通过函数计算
4)构造函数 替代 字符串拼接,字符串拼接和类型转换耗费CPU
5)冗余代码删除,错误情况:第一个还款日晚于借款结束日期,也不可能是按月还款了,应该在UI里面、或者函数开头处理掉,不应该在算法内部
5)类型重构,减少类型转换,删除无用中间变量
同时enddate变量属于重新定义,去掉
二 对象定义的简单方式
三 计算错误
对“每期归还本金”进行四舍五入之后,剩余本金发生变化,通过“0.004”这种方式是错误的。
移入循环,算法改成:
1)本次归还本金=剩余本金/剩余期数
2)本次归还本金四舍五入
3)修改剩余本金、剩余期数
四 重复代码消除
1.分析
代码主体分成2块,
第一块是实际计息日等于还贷日(5日计息,5日还贷)
第二块是实际计息日不等于还贷日(5日计息,10日还贷,中间不免息。。5日计息,3日还贷,中间不免息)
这两块通过if else控制,内里充斥无数重复代码
比如以下,导致代码数量激增
2. 数据错误在开头就应该处理好,这样能尽早给出提示, 减少函数内部执行时间
重复代码提取之后,与外面类似代码合并
3.处理算头也算尾需求,原先代码两个问题:
a if else代码块分别都有计算,重复
b 只处理了实际借款天数,没有处理还款日,算头的情况,还款日需要提前一天
[修改计息日为实际计息日即可]
原先代码:
修改后代码:
五 计息日!=还贷日时,第一期利息计算错误
六 业务场景和思路问题
1)首先还贷日应该根据放款日自动生成
2)即使是如下两种情况
a)第一块是实际计息日等于还贷日(5日计息,5日还贷)
b)第二块是实际计息日不等于还贷日(5日计息,10日还贷,中间不免息。。5日计息,3日还贷,中间不免息)
在实际实现的时候, if else也应该调换,因为第一块是第二块的简化情况
解决完第一期,修改初始情况,中间期数算法等于第一块,然后剩下最后一期,最后一期和第一期算法相同。
3)如果遵守第一个情况,那么第二种的复杂情况不会产生。
删除if语句块
七 借款周期计算问题
1) 天数/每月天数(实际天数,和固定为30天)
2) 根据借款月数转换
八 重构为策略模式
具体模式介绍:http://www.cnblogs.com/promise-7/archive/2012/05/29/2524357.html
策略又称做政策(Policy)模式【GOF95】。下面是一个示意性的策略模式结构图:
这个模式涉及到三个角色:
- 环境(Context)角色:持有一个Strategy类的引用。
- 抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
- 具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。
1)目前的结构是这样的
一个类有很多不同的算法函数
2)我们需要重构成
一个抽象类,各种算法继承这个抽象类,实现类通过实例化抽象类使用具体的算法
a)定义需要被继承的类
b)定义继承上述类的算法
c)如下代码重构到Calc()方法内
重构后如下,为什么注释掉isInt,isInt的现实意义是付款方便,如果是为了付款方便,那么应该本金和利息相加后取整
调用处这么写就可以了
RepaymentPlanCalc rPlanCalc = new AverageCapital(myRateCalc.Borrowsum, totalqishu, myRateCalc.Borrowrate, time1);
backlist = rPlanCalc.Calc();