技术开发 频道

敏捷开发的必要技巧(一)

【IT168 技术文章】    重复代码是怎么产生的?
    请观察下面的代码。我们已经有一个根据出租记录的id取出租用客户姓名的方法:

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方法一样,deleteRental方法也要一个一个遍历出租记录,所以将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很可能是短时间内发现不了的。

0
相关文章