重复代码是怎么产生的?
请观察下面的代码,我们已经有一个根据出租记录的id取出租用客户姓名的方法:getcustomername。
假定现在你要增加一个新的方法,该方法是根据出租记录的id删除该记录,你把这方法命名为deleterental(string rentalid)。现在你已经考虑到,就像getcustomername这个方法一样,也要一个一个遍历出租记录。所以你就将getcustomername这个方法里面的一些代码拷出来,然后稍微修改一下:
现在这样的代码看起来怎么样?不怎么样,两个方法有大多的同样的代码了。
移除重复代码吧!
要移除所有的重复代码,你可以将bookrentals这个类修成如下的样子(也就是“重构”了):
为什么我们要移除重复代码?
我来向各位程序员同学稍微说一下,在bookrentals这个类中,rentals这个属性的类型是ventor,如果我们需要将它改为数组,那我们就必须将所有的"rentals.size()"改为"rentals.length". 在重构以后的版本中,我们只需要在getrentalidxbyid这个方法中修改一次,而在原来的版本,我们就得在getcustomername跟deleterental两个方法中都改一次。类似的,我们还要将所有的"rentals.elementat(i)" 改为 "rentals[i]". 又是改一次跟改两次的比较!
大多数情况中,如果类似这样的代码在10个地方重复,当我们修改代码的时候,就要修改10个地方,我们并不能保证能把这10个地方都记住了,而一旦漏掉了几个地方,等待我们的,是一处一处的错误去修复。而最致命的是,当我们修改的是业务逻辑时,这时候,不管我们漏掉了几个地方,ide都不会报错,那么,等待我们的,将是一堆bug去检查,而造成的一些bug中,很可能是短时间内还发现不了的. 惨-_-!!
请观察下面的代码,我们已经有一个根据出租记录的id取出租用客户姓名的方法:getcustomername。
public class bookrental { //该类描述出租记录
string id;
string customername;
...
}
public class bookrentals {
private vector rentals;
public string getcustomername(string rentalid) { 根据出租id取出客户姓名
for (int i = 0; i < rentals.size(); i++) {
bookrental rental = (bookrental) rentals.elementat(i);
if (rental.getid().equals(rentalid)) {
return rental.getcustomername();
}
}
throw new rentalnotfoundexception();
}
}
public class rentalnotfoundexception extends exception {
...
} 假定现在你要增加一个新的方法,该方法是根据出租记录的id删除该记录,你把这方法命名为deleterental(string rentalid)。现在你已经考虑到,就像getcustomername这个方法一样,也要一个一个遍历出租记录。所以你就将getcustomername这个方法里面的一些代码拷出来,然后稍微修改一下:
public class bookrentals {
private vector rentals;
public string getcustomername(string rentalid) {
for (int i = 0; i < rentals.size(); i++) {
bookrental rental = (bookrental) rentals.elementat(i);
if (rental.getid().equals(rentalid)) {
return rental.getcustomername();
}
}
throw new rentalnotfoundexception();
}
public void deleterental(string rentalid) {
for (int i = 0; i < rentals.size(); i++) {
bookrental rental = (bookrental) rentals.elementat(i);
if (rental.getid().equals(rentalid)) {
rentals.remove(i);
return;
}
}
throw new rentalnotfoundexception();
}
} 现在这样的代码看起来怎么样?不怎么样,两个方法有大多的同样的代码了。
移除重复代码吧!
要移除所有的重复代码,你可以将bookrentals这个类修成如下的样子(也就是“重构”了):
public class bookrentals {
private vector rentals;
public string getcustomername(string rentalid) {
int rentalidx = getrentalidxbyid(rentalid);
return ((bookrental) rentals.elementat(rentalidx)).getcustomername();
}
public void deleterental(string rentalid) {
rentals.remove(getrentalidxbyid(rentalid));
}
private int getrentalidxbyid(string rentalid) { //新增加的一个方法
for (int i = 0; i < rentals.size(); i++) {
bookrental rental = (bookrental) rentals.elementat(i);
if (rental.getid().equals(rentalid)) {
return i;
}
}
throw new rentalnotfoundexception();
}
} 为什么我们要移除重复代码?
我来向各位程序员同学稍微说一下,在bookrentals这个类中,rentals这个属性的类型是ventor,如果我们需要将它改为数组,那我们就必须将所有的"rentals.size()"改为"rentals.length". 在重构以后的版本中,我们只需要在getrentalidxbyid这个方法中修改一次,而在原来的版本,我们就得在getcustomername跟deleterental两个方法中都改一次。类似的,我们还要将所有的"rentals.elementat(i)" 改为 "rentals[i]". 又是改一次跟改两次的比较!
大多数情况中,如果类似这样的代码在10个地方重复,当我们修改代码的时候,就要修改10个地方,我们并不能保证能把这10个地方都记住了,而一旦漏掉了几个地方,等待我们的,是一处一处的错误去修复。而最致命的是,当我们修改的是业务逻辑时,这时候,不管我们漏掉了几个地方,ide都不会报错,那么,等待我们的,将是一堆bug去检查,而造成的一些bug中,很可能是短时间内还发现不了的. 惨-_-!!
闽公网安备 35060202000074号