第一章看到一个很有趣的一句话,就是当进行重构的时候,为即将修改的代码建立一组可靠的测试环境。
贴上一个看到的一组测试代码。
class CAL
{
public:
int add(int val1,int val2)
{
return val1+val2;
}
};
CAL cal;
namespace test_env
{
void test_case1()
{
int val1= 100;
int val2 = 200;
assert(cal.add(val1,val2) == val1+val2);
}
void test_case2()
{
int val1= -20000;
int val2 = -10000;
assert(cal.add(val1,val2) == val1+val2);
}
void run_case()
{
test_case1();
test_case2();
cout<<"pass case"<<endl;
}
}
int main()
{
test_env::run_case();
return 0;
}
书里面讲了很多道理,我比较有体会的几个道理。
-
重复代码
-
过长的函数
一个函数的代码过于多,这个表示函数里面想做的事情太多了。违背单一职责的原则。
-
过大的类
-
过长的参数列表
-
少用switch-case
(这个我目前还不是很理解)
后来,我似乎有点理解了,用switch-case的场景可能是一个函数尝试去做很多事情。如果是这种情况去使用swich-case的话,那就要谨慎一点了。
-
写测试的价值
这一张其实讲了一个很好的点,就是面向测试去写代码。在开发的时候,花一点时间去写一份test-case,这样,反而在后面的增量开发的时候,这样应该可以更加提高效率。
-
replace temp with query
以查询取代临时变量
-
introduce explaining variable
将复杂的表达式的结果放进一个临时变量里面,以此变量名来解释表达式的用途。
-
替换算法
void solution(const vector<string> & people) { for(int i=0;i<people.size();i++) { if(people[i] == "xxxx0") { } if(people[i] == "xxxx1") { } } }可以替换成
void solution(const vector<string> & people) { for(int i=0;i<people.size();i++) { handle_element(people[i]); } }这个也算是遵守单一指责原则,函数只负责一件事情,不要太长。
-
以对象取代数据值
程序设计应该有弹性,比如程序一开始需要要一个字符串表示电话号码,但是后面加入了“区号”等东西。这样更好的方式就是新建一个电话号码的类,将新的数据成员都放到里面。上层使用电话号码类的对象。
-
以多态取代条件表达式
-
引入断言assert
-
函数名称
给函数起一个很合适的名字非常重要,给函数起名字的一个好办法就是,首先应该考虑给这个函数写一个注释,然后想办法让这个注释成为函数的名字。
-
将查询函数和修改函数进行分离
如果要做一件事情,需要两个步骤,查询和修改。最好把这两个步骤拆分开来,不要在一个函数里面完成这个两个事情。
-
将没有被类外部的函数调用的函数设置为private
-
以委托取代继承
去掉子类继承父类的方式,而是之类实例化一个父类的对象,并把它作为数据成员。以this->的方式去调用。
-
将逻辑和业务分离
MVC里面的model和view之间是会分层的,处理model的代码里面,不应该设计业务层的代码。换一句话说,底层的代码里面不应该包含高层的代码。