资讯专栏INFORMATION COLUMN

重构-改善既有代码的设计(一)--重构,第一个案例

acrazing / 2903人阅读

摘要:并根据目录选读第章重构,第一个案例这是只是一个方法。绝大多数情况下,函数应该放在它所使用的数据的所属对象内最好不要在另一个对象的属性基础上运用语句。

什么是重构

在不改变代码外在行为的前提下,对代码做出修改以改进程序内部的结构
简单地说就是在代码写好后改进它的设计

谁该阅读这本书

专业程序员(能够提高你的代码质量)

资深设计师和架构规划师(理解为什么需要重构,哪里需要重构)

阅读技巧

带着疑问去读:

如果你想要知道重构是什么。第1章够了

如果你想要知道为什么要重构,第1,2章

如果你想知道该在什么地方重构,第3章

如果你想进行重构,第1,2,3,4章。并根据目录选读

第1章 重构,第一个案例
public String statement(){

        double totalAmount=0;
        int frequentRenterPoints=0;
        Enumeration rentals = _rentals.elements();

        String result = "Rental Record for "+getName()+"
";
        while(rentals.hasMoreElements()){

            double thisAmount=0;
            Rental each = (Rental)rentals.nextElement();

            switch (each.getMovie().getPriceCode()) {
            case Movie.CHILDRENS:

                thisAmount += 1.5;
                if(each.getDaysRented()>3){
                    thisAmount += (each.getDaysRented()-3)*1.5;
                }
                break;
            case Movie.NEW_RELEASE:

                thisAmount += each.getDaysRented()*3;
                break;
            case Movie.REGULAR:

                thisAmount += 2;
                if(each.getDaysRented()>2){
                    thisAmount += (each.getDaysRented()-2)*1.5;
                }
                break;

            default:
                break;
            }

            frequentRenterPoints++;

            if(each.getMovie().getPriceCode()==Movie.NEW_RELEASE && each.getDaysRented()>1)frequentRenterPoints++;

            result += "	"+each.getMovie().getTitle()+"	"+String.valueOf(thisAmount)+"
";
            totalAmount +=thisAmount;

        }

        result += "Amount owed is " + String.valueOf(totalAmount) + "
";

        result += "You earned " + String.valueOf(frequentRenterPoints) + " frequent renter points ";

        return result;
    }

这是只是一个方法。直接评价:太复杂,复用率低

解决方法 分解并重组

将代码按照功能拆分。每个功能只做一件事。

拆除switch并封装为方法
private double amountFor(Rental each, double result) {
    switch (each.getMovie().getPriceCode()) {
    case Movie.CHILDRENS:

        result += 1.5;
        if(each.getDaysRented()>3){
            result += (each.getDaysRented()-3)*1.5;
        }
        break;
    case Movie.NEW_RELEASE:

        result += each.getDaysRented()*3;
        break;
    case Movie.REGULAR:

        result += 2;
        if(each.getDaysRented()>2){
            result += (each.getDaysRented()-2)*1.5;
        }
        break;

    default:
        break;
    }
    return result;
}



重设变量名

变量名必须保证简单清楚,不产生歧义。比如上方代码的each就是可修改的变量名。因为each到底指的是什么

搬移代码

因为这个方法只使用了rental的信息。所以需要放在rental类下

去除临时变量

statement方法中有两个临时变量totalAmount和frequentRenterPoints。 做成getTotalAmount和getFrequentRenterPoints方法

public String statement() {
        double totalAmount = 0;
        int frequentRenterPoints = 0;
        // Enumeration接口定义了从一个数据结构得到连续数据的手段
        Enumeration rentals = _rentals.elements();

        String result = "Rental Record for" + getName() + "
";
        while (rentals.hasMoreElements()) {
            Rental each = (Rental) rentals.nextElement();

            result += "	" + each.getMovie().getTitle() + "	" + String.valueOf(each.getMovie().getPrice().getCharge(each.getDayRented())) + "
";


        }
        result += "Amount owed is " + String.valueOf(getTotalCharge()) + "
";
        result += "You earned " + String.valueOf(getTotalFrequentRenterPoints()) + "frequent renter points";

        return result;

    }
private int getTotalFrequentRenterPoints(){
    int result=0;
    Enumeration rentals=_rentals.elements();
    while(rentals.hasMoreElements()){
        Rental each=(Rental)rentals.nextElement();
        result+=each.getMovie().getFrequentRenterPoints(each.getDayRented());
    }
    return result;
}
private double getTotalCharge(){
    double result =0;
    Enumeration rentals=_rentals.elements();
    while(rentals.hasMoreElements()){
        Rental each=(Rental)rentals.nextElement();
        result+=each.getMovie().getPrice().getCharge(each.getDayRented());
    }
    return result;
}
测试重构后的方法

保证重构后的方法能够满足所有的需求

总结

代码块俞小,代码的功能就俞容易管理,代码的处理和移动也就俞轻松

任何不会被修改的变量都可以被当成参数传入新的函数,至于会被修改的变量需要慎重。如果只有一个变量会被修改,可以把它当做返回值。

绝大多数情况下,函数应该放在它所使用的数据的所属对象内

最好不要在另一个对象的属性基础上运用switch语句。如果不得不使用,也应该在对象自己的数据上使用,而不是在别人的数据上使用。

使用继承来适当组织类关系后,可以用多态取代switch语句。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/69675.html

相关文章

  • 读书笔记《重构 改善既有代码设计

    摘要:重构在不改变代码的外在的行为的前提下对代码进行修改最大限度的减少错误的几率本质上,就是代码写好之后修改它的设计。重构可以深入理解代码并且帮助找到。同时重构可以减少引入的机率,方便日后扩展。平行继承目的在于消除类之间的重复代码。 重构 (refactoring) 在不改变代码的外在的行为的前提下 对代码进行修改最大限度的减少错误的几率 本质上, 就是代码写好之后 修改它的设计。 1,书中...

    mdluo 评论0 收藏0
  • 重构-改善既有代码设计(五)--重构列表

    摘要:什么是重构列表重构方法需要以一种特定的格式记录下来。这些重构手法到底有多成熟本书中提到的重构手法第章。做法创造新函数,以用途命名提炼代码到函数中检查变量名是否符合规范在源函数中,将被提炼代码替换为函数引用测试范例重构前重构后 什么是重构列表 重构方法需要以一种特定的格式记录下来。按照格式记录下来的重构方法的集合叫重构列表 重构的记录格式 每个重构手法可分为5个部分: 名称 构建重构词汇...

    davidac 评论0 收藏0
  • 重构-改善既有代码设计》读书笔记-重构

    摘要:重构改善既有代码设计动词使用一系列重构手法,在不改变软件可观察行为的前提下,调整其结构。修补错误时重构代码时重构怎么重构关于代码的重构技巧参考重构改善既有代码设计读书笔记代码篇个人博客 重构定义 名词 对软件内部结构的一种调整,目的是在不改变软件可观察行为的前提下,提高其可理解性,降低其修改成本。——《重构-改善既有代码设计》 动词 使用一系列重构手法,在不改变软件可观察行为的前提下,...

    ermaoL 评论0 收藏0
  • 重构-改善既有代码设计(二) --重构原则

    摘要:改进代码设计的一个重要原则就是消除重复代码使软件更容易被理解优秀的代码能够让接收你代码的付出更少的学习成本。重构更容易找到重构能加深对代码的理解。可以重构的情况添加功能时可以重构。说明你没有发现代码的错误。需要重构复审代码时可以重构。 为何重构 重构不是银弹,但是帮助你达到以下几个目的 改进软件设计 不良的程序需要更多的代码。而代码越多,正确的修改就越困难。改进代码设计的一个重要原则就...

    myshell 评论0 收藏0
  • 重构---改善既有代码设计》之简化条件表达式

    那有什么天生如此,只是我们天天坚持。 本篇文章主要讲解 《重构---改善既有代码的设计》 这本书中的 第九章简化条件表达式中 的知识点, Decompose Conditional(分解条件表达式) 问题:你有一个复杂的条件(if、then、else) 语句 解决:从if、then、else三个段落中分别提炼出独立函数 //重构前 if (date.before(SUMMER_START) |...

    Cheng_Gang 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<