`
oaklet
  • 浏览: 107823 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

重构学习笔记

    博客分类:
  • java
阅读更多
引子
过度设计,是指代码的灵活性和复杂性超出所需。他们之所以这样做,是希望今天就把方案设计得更加灵活、更复杂,以适应明天的需求。如果预计中的需求分配不会成为现实,浪费的将是宝贵的时间和金钱。为了避免这一问题,分头负责系统的各个部分。但是每个人都在自己的小天地里工作,很少看别处代码是否已经完成了自己需要的功能,最后产生大量的重复代码。
模式万灵药,模式代表的是一种灵活、精妙,非常优雅的面向对象设计方法。模式的强大容易使人对简单的代码编写方式视而不见。把精力放在短小、简单和直截了当的代码上,可以使你减少过度设计。
设计不足,这个比过度设计要常见得多。产生原因有以下几种:
  • 程序员没有时间,没有抽出时间,或者时间不允许重构。
  • 程序员在好的软件设计方面知识不足。
  • 程序员被要求在既有系统中快速地添加新功能。
  • 程序员补充被迫同时进行太多的项目。

长期的设计不足,可能造成如下后果:
  • 系统的1.0版本很快就交付了,但是代码质量很差。
  • 系统的2.0版本也交付了,但质量低劣的代码使我们慢了下来。
  • 在企图交付未来版本时,随着劣质代码的倍增,开发也越来越慢,最后人们对系统、程序员乃至使大学陷于这种境地的整个过程都失去了信心。
  • 到了4.0版或者之后,我们意识到这样肯定不行,开始考虑推倒重来。

测试驱动和持续重构,两个实践能帮助降低过度设计和设计不足的几率。
演进式设计,关于软件设计的资料更多的集中在讲授优秀的解决方案上,而对于这些解决方案的演变过程不够重视。演变所得到的设计结构虽然有些帮助,但是不知道设计如何发展而来的,在一下项目中你就很可能错误的应用,或者陷入过度设计的误区。
了解优秀软件设计的演变过程比学习优秀设计本身更有价值。

Extract Method
Turn the fragment into a method whos name explains the purpose of the method.
将这段代码放入一个独立的方法中,让方法名来解释方法的用途。
    void printOwing(double amount) {
        printBanner();

        // print details
        System.out.println("name" + _name);
        System.out.println("amount" + _amount);
    }

    void printOwing(double amount) {
        printBanner();
        printDetails(amount);
    }

    void printDetails(double amount) {
        System.out.println("name" + _name);
        System.out.println("amount" + _amount);
    }

Inline Method
Put the method's body into the body of its callers and remove the method.
    int getRating() {
        return (moreThanFiveLateDeliveries()) ? 2 : 1;
    }

    boolean moreThanFiveLateDeliveries() {
        return _numberOfLateDeliveries > 5;
    }

    int getRating() {
        return (_numberOfLateDeliveries > 5) ? 2 : 1;
    }

InlineTemp
        double basePrice = anOrder.basePrice();
        return (basePrice > 1000);

        return (anOrder.basePrice() > 1000);

Replace Temp with Query
    public double getPrice () {
        double basePrice = _quantity * _itemPrice;
        if (basePrice > 1000)
            return basePrice * 0.95;
        else
            return basePrice * 0.98;
    }

    public double getPrice () {
        if (basePrice() > 1000)
            return basePrice() * 0.95;
        else
            return basePrice() * 0.98;
    }

    double basePrice() {
        return _quantity * _itemPrice;
    }

Introduce Explaining Variable
        if ((platform.toUpperCase().indexOf("MAC") > -1)
                && browser.toUpperCase().indexOf("IE") > -1
                && wasInitialized() && resize > 0) {
            // do something
        }

        final boolean isMacOs = platform.toUpperCase().indexOf("MAC") > -1;
        final boolean isIEBrowser = browser.toUpperCase().indexOf("IE") > -1;
        final boolean wasResized = resize > 0;
        if (isMacOs && isIEBrowser && wasInitialized() && wasResized) {
            // do something
        }

Split Temporary Variable
        double temp = 2 * (_height + _width);
        System.out.println(temp);
        temp = _height * _width;
        System.out.println(temp);

        final double perimeter = 2 * (_height + _width);
        System.out.println(perimeter);
        final double area = _height * _width;
        System.out.println(area);

Remove Assignments to Parameters
    int discount(int inputVal, int quantity, int yearToDate) {
        if (inputVal > 50)
            inputVal -= 2;
        if (quantity > 100)
            inputVal -= 1;
        if (yearToDate > 10000)
            inputVal -= 4;
        return inputVal;
    }

    int discount(int inputVal, int quantity, int yearToDate) {
        int result = inputVal;
        if (inputVal > 50)
            result -= 2;
        if (quantity > 100)
            result -= 1;
        if (yearToDate > 10000)
            result -= 4;
        return result;
    }

Replace Method with Method Object
class Account {

    int gamma(int inputVal, int quantity, int yearToDate) {
        int importantValue1 = (inputVal * quantity) + dalta();
        int importantValue2 = (inputVal * yearToDate) + 100;
        if ((yearToDate - importantValue1) > 100)
            importantValue2 -= 20;
        int importantValue3 = importantValue2 * 7;
        // and so on
        return importantValue3 - 2 * importantValue1;
    }
}

class Account {

    int gamma(int inputVal, int quantity, int yearToDate) {
        return new Gamma(this, inputVal, quantity, yearToDate).compute();
    }
}

class Gamma {
    private Account _account;
    private int inputVal;
    private int quantity;
    private int yearToDate;

    public Gamma(Account _account, int inputVal, int quantity, int yearToDate) {
        this._account = _account;
        this.inputVal = inputVal;
        this.quantity = quantity;
        this.yearToDate = yearToDate;
    }

    int compute() {
        int importantValue1 = (inputVal * quantity) + _account.dalta();
        int importantValue2 = (inputVal * yearToDate) + 100;
        if ((yearToDate - importantValue1) > 100)
            importantValue2 -= 20;
        int importantValue3 = importantValue2 * 7;
        // and so on
        return importantValue3 - 2 * importantValue1;
    }
}

Substitute Algorithm
    String foundPerson(String[] people) {
        for (int i = 0; i < people.length; i++) {
            if (people[i].equals("Don")) {
                return "Don";
            }
            if (people[i].equals("Jonh")) {
                return "Jonh";
            }
            if (people[i].equals("Kent")) {
                return "Kent";
            }
        }
        return "";
    }

    String foundPerson(String[] people) {
        List<String> candidates = Arrays.asList(
                new String[] { "Don", "Jonh", "Kent" });
        for (int i = 0; i < people.length; i++) {
            if (candidates.contains(people[i]))
                return people[i];
        }
        return "";
    }

……
分享到:
评论

相关推荐

    31天重构学习笔记中文版

    31天重构学习笔记中文汉化版,非常好的编程规范书籍

    重构 学习笔记 refactoring martin fowler

    “每当我要进行重构的时候, 第一个步骤永远相同: 我得为即将修改的代码建立一组可靠的测试环境. 这些测试是必要的, 因为尽管遵循重构准则可以使我避免绝大多数的臭虫引入机会, 但我毕竟是人, 毕竟有可能犯错误. ...

    31天重构学习笔记.docx

    这个重构在微软的代码库也经常遇到。比如最经典的属性对字段的封装就是一个很好的例子,那么下面我们将看到对集合的封装,如下代码所示,调用端只需要一个集合的信息,而我们则提供了一个IList的集合,大家都知道...

    [免费高清PDF]31天重构系列笔记.rar

    [免费高清PDF]31天重构系列笔记.rar [免费高清PDF]31天重构系列笔记.rar

    .NET 快速重构 - 学习笔记

    重构是持续改进代码的基础。抵制重构将带来技术麻烦:忘记代码片段的功能、创建无法测试的代码等等。 而有了重构,使用单元测试、共享代码以及更可靠的无 bug 的代码这些最佳实践就显得简单多了。

    《重构》----学习笔记

    重构不是一项靠着天分挥洒的艺术,而是一项工程。重构是一种有纪律的,经过训练的,有条不紊的程序整理方案,可以将整理过程中不小心引入错误的机率降到最低

    JSP_Servlet学习笔记(第2版).pdf

    《JSP & Servlet学习笔记(第2版)》是作者多年来教学实践经验的总结,...《JSP & Servlet学习笔记(第2版)》以“微博”项目贯穿全书,将JSP & Servlet技术应用于实际项目开发之中,并使用重构方式来改进应用程序架构。

    重构:改善既有代码的设计(第2版)学习笔记

    重构:改善既有代码的设计(第2版)学习笔记

    C#学习笔记

    我个人觉得面向对象是本本主义、洁癖的体现、是重构后的最后归属、它可能会矫情、在市场变化老板着急产品狭隘的情况下 快速制作快速上线才是王道,面向对象的基础是对事物的详尽认知,短时间内能做到吗 不好做到,...

    重构知识总结篇

    有关系统重构知识总结,网上浏览学习笔记。

    refactoring-to-patterns-notes:重构-向范式前进(重构为模式)的学习笔记

    重构为模式注释重构-向范式前进(重构为模式)的学习笔记。本站网址: : 本书已绝版,请参考。欢迎到讨论或指正错误。

    docker 学习笔记.docx

    最近老项目重构,打算使用Docker虚拟化技术,踩着坑整理的。希望帮助能够帮助的人。

    W3学习笔记--文献检索与有效阅读1

    标题摘要介绍难度2 详读并 记笔记可转述正标出不理解的名间 提问批判性思考改进重构作者的作到新 不是③献综述 学术观点 t 理论法1批判性归纳与评论堆砌只研究意

    AppFuse学习笔记(J2EE入门级框架)

    Appfuse是Matt Raible 开发的一个指导性的入门级J2EE框架,它对如何集成流行的Spring、Hibernate、iBatis、Struts、xDcolet、Junit、Taperstry、JSF等基础框架给出...AppFuse2.0重构了AppFuse1.0,转到Maven2和Jdk1.5。

    appfuse 学习笔记

    Appfuse 一个开放源码的项目和应用程序,帮助我们快速而高效的地开发。 Appfuse是Matt Raible 开发的一个指导性的入门级J2EE框架,它对如何集成流行的Spring、...AppFuse2.0重构了AppFuse1.0,转到Maven2和Jdk1.5。

    Java学习笔记-个人整理的

    \contentsline {chapter}{Contents}{2}{section*.1} {1}Java基础}{17}{chapter.1} {1.1}基本语法}{17}{section.1.1} {1.2}数字表达方式}{17}{section.1.2} {1.3}补码}{19}{section.1.3} {1.3.1}总结}{23}{...

    angular 学习笔记

    前提 Angular1.5 到 Angular4.0是重写的语言,Angular1简称...在Angular知识学习(一)中有讲述到表单的知识,不过那是最基础的演示,在之后的学习中又了解到模板驱动表单,所以考虑对之前的表单案例进行重构,完善表单

    《xUnitTestPatterns》学习笔记系列

    学习笔记1-TestSmell这本书找来很久了,一直没读。关于软件测试的好书相当少,对于测试代码的重构及模式的书就更加难得了。虽然我才读了前几章,给我的感受是,这本书确实讲的很全面,并且给很多测试中的东西给出了...

Global site tag (gtag.js) - Google Analytics