wangshouchang

重构 -改变既有代码的设计 ---- 笔记

目录

这是一篇《重构 》的总结 ,我在学习的同时并使用它作为参考。这不是一本书的替代品,所以你要想真的想学习里面的内容,买一本书使用这个文章作为参考和指南。

另外: 建议 评论 还 PR 都是十分欢迎的

1. TABLE OF CONTENT

3. BAD SMELLS IN CODE(代码的坏味道)

1. Duplicated code (重复的代码)

多个地方使用相同的代码

2. Long Method(很长的方法)

一个很长的程序是很难被理解的

3. Large Classes(超级大的类)

当一个类变的越来越大的时候,是难以阅读的

4. Long Parameter List(长参数列表)

长参数是很难去理解,不符合也较难使用

5. Divergent Change(发散的改变)

当一个类经常因为不同原因发生在不同的方向发生变化

6. Shotgun Surgery(散弹枪修改)

每次你做一小部分修改时,都不的不需要做大量的修改在很多不同的类中

7. Feature Envy(依恋情结)

某个方法似乎在另外的类的兴趣高于自己所处的类

8. Data Clumps(数据泥团)

一堆数据杂糅在一起(字段, 参数)

9. Primitive Obsession(基本类型偏执)

使用基本类型替代小对象

10. Switch Statements(Switch 惊悚现身)

当程序中出现很多 switch 语句在很多地方,使用多态来进行替换

11. Parallel Inheritance Hierarchies(平行继承类)

每当你为一个类增加一个子类,你不得不为另一个类增加相应的一个子类

12. Lazy Class(冗余类)

当一个类不足与为其自身买单它就应该被删除

13. Speculative Generality(夸夸其谈未来性)

所有的钩子和特殊情况处理那些不需要的

14. Temporary Field(令人迷惑的临时变量)

一个临时变量仅仅为某种特殊情况做而定,这样的代码让人难以理解

15. Message Chain(过长的消息链)

当一个类请求调用一个对象,但是这个类又在调用其他的方法

16. Middle Man(中间人)

当一个对象委托大部分功能,开发中可能会过度的使用委托模式,导致某个类中的方法大都委托给其他方法处理

17. Inappropriate Intimacy(不恰当的亲密关系)

当两个类过度的亲密,需要将其拆散

18. Alternative Classes with Different Interfaces(异曲同工的类)

类的方法过度相似

19. Incomplete Library Class(不完美的库)

当我们使用外部依赖库时

20. Data Class(数据类)

不要操作数据类,我们通过封装它的不变性

21. Refused Bequest(被拒绝的遗赠)

子类不想使用父类的方法

22. Comments(过多没用的注释)

当一个方法使用过度的注释解释其中的逻辑时,说明这个方法应该被重构了。

6. COMPOSING METHODS(重新组织函数))

1. Extract Method(提炼函数)

你可以将一些代码组合起来,然后放到一个方法中


    void printOwing(double amount) {
        printBanner();
        //print details
        System.out.println ("name:" + _name);
        System.out.println ("amount" + amount);
    }

to


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

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

动机

  • 增加代码被复用的机会
    * 阅读方法就像阅读一系列声明一样简单

    void printOwing(double previousAmount) {
        Enumeration e = _orders.elements();
        double outstanding = previousAmount * 1.2;
        printBanner();

        // calculate outstanding
        while (e.hasMoreElements()) {
            Order each = (Order) e.nextElement();
            outstanding += each.getAmount();
        }
        printDetails(outstanding);
    }

to


    void printOwing(double previousAmount) {
        printBanner();
        double outstanding = getOutstanding(previousAmount * 1.2);
        printDetails(outstanding);
    }

    double getOutstanding(double initialValue) {
        double result = initialValue;
        Enumeration e = _orders.elements();

        while (e.hasMoreElements()) {
            Order each = (Order) e.nextElement();
            result += each.getAmount();
        }
        return result;
    }

2. Inline Method (内联函数)

一个函数本体和函数名称一样容易理解


    int getRating() {
        return (moreThanFiveLateDeliveries()) ? 2 : 1;
    }

    boolean moreThanFiveLateDeliveries() {
        return _numberOfLateDeliveries > 5;
    }

to


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

动机

  • 当间接不是必要的时候
  • 当一组方法被严格的分解,会使这个方法变得清晰

3. Inline Temp (内联临时变量)

你申明了一个临时的变量在一段表达里面,然后临时的变量将会阻挡你重构


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

to


    return (anOrder.basePrice() > 1000)

Motivation

4. Replace Temp with Query (以查询取代临时变量)

你正在使用临时变量来保存表达式的结果


    double basePrice = _quantity * _itemPrice;
    if (basePrice > 1000){
        return basePrice * 0.95;
    }
    else{
        return basePrice * 0.98;
    }

to


    if (basePrice() > 1000){
        return basePrice() * 0.95;
    }
    else{
        return basePrice() * 0.98;
    }
    ...
    double basePrice() {
        return _quantity * _itemPrice;
    }

动机

  • 使用方法代替临时变量,类中的任何方法都可以获取信息
  • 这是一个十分重要的步骤在其之前1. Extract Method

5. Introduce Explaining Variable (引入解释性变量)

有一个复杂的表达式


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

to


    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
    }

动机

  • 当一个表达式难以理解时

6. Split Temporary Variable (分解临时变量)

分类:

技术点:

相关文章:

  • 2021-06-05
  • 2021-04-01
  • 2021-06-14
  • 2021-11-08
  • 2021-07-04
  • 2021-05-26
  • 2022-01-05
  • 2020-12-19
猜你喜欢
  • 2021-12-15
  • 2021-11-12
  • 2021-09-13
  • 2021-07-14
  • 2021-09-13
  • 2021-06-19
  • 2022-01-08
相关资源
相似解决方案