精华内容
下载资源
问答
  • Android 代码重构案例
    千次阅读
    2022-03-30 09:39:03

    很久之前读过一本书《重构,改善既有代码设计》,这本书对自己的影响很大,里面的一些实用性技巧现在还在保持和使用。
    今天阅读团队小伙伴的代码,发现了这么一段:

    private void setTextViewData(int type) {
       
       switch (type) {
       
            case 1:
                textView.setText("aaaa")
    更多相关内容
  • 背景日常开发经常会遇到复杂的条件判断, 一般做法就是用if/else, 或者优雅一点用switch来...案例先来看一段代码:const clickHandler = (status) => {if(status === 1) {sendLog('processing')jumpTo('IndexPag...

    背景

    日常开发经常会遇到复杂的条件判断, 一般做法就是用if/else, 或者优雅一点用switch来实现多个条件的判断. 如果条件越来越多, 会导致代码越来越臃肿, 如何使用更优雅的方式来实现呢?

    案例

    先来看一段代码:

    const clickHandler = (status) => {

    if(status === 1) {

    sendLog('processing')

    jumpTo('IndexPage')

    } else if(status === 2) {

    sendLog('fail')

    jumpTo('FailPage')

    } else if(status === 3) {

    sendLog('fail')

    jumpTo('FailPage')

    } else if(status === 4) {

    sendLog('success')

    jumpTo('SuccessPage')

    } else if(status === 5) {

    sendLog('cancel')

    jumpTo('CancelPage')

    } else {

    sendLog('other')

    jumpTo('Index')

    }

    }

    优化1

    通过以上代码, 可以看出该函数的作用是: 根据status状态的不同, 发送日志和跳转到对应的页面.

    大家可以轻易的使用switch来进行重构:

    const clickHandler = (status) => {

    switch (status) {

    case 1:

    sendLog('processing')

    jumpTo('IndexPage')

    break

    case 2:

    case 3:

    sendLog('fail')

    jumpTo('FailPage')

    break

    case 4:

    sendLog('success')

    jumpTo('SuccessPage')

    break

    case 5:

    sendLog('cancel')

    jumpTo('CancelPage')

    break

    default:

    sendLog('other')

    jumpTo('Index')

    }

    }

    这样看起来比if / else清晰多了. 细心的你一定会发现case2, case3的逻辑是一样的,

    优化2

    在日常的代码开发中, 基本上大多数同学都是这样写. 这样写固然可以, 但也不太优雅.

    有一观点是: 编程的本质, 数据结构 + 算法, 任何算法都包含两部分, Logic + Control

    Logic部分就是真正意义上的算法

    Control部分只是影响解决问题的效率.

    如果我们能将 Logic 和 Control部分有效地分开, 那么代码将会变得更加容易维护和改进.

    比如, 我们试着用下面的办法去分离代码:

    const actions = {

    '1': ['processing', 'IndexPage'],

    '2': ['fail', 'FailPage'],

    '3': ['fail', 'FailPage'],

    '4': ['success', 'SuccessPage'],

    '5': ['cancel', 'CancelPage'],

    'default': ['other', 'Index']

    }

    const clickHandler = (status) => {

    let action = actions[status] || actions['default'],

    LogName = action[0],

    pageName = action[1]

    sendLog(LogName)

    jumpTo(pageName)

    }

    这样的形式, 其实就是DSL(Domain Specific Language)解析器. DSL的描述是一个Logic, 函数clickHandler就是Control部分, 代码大大简化,

    小结

    由此可以总结出如下思想:

    State Machine

    状态定义

    状态变迁条件

    状态的action

    DSL - Domain Specific Language

    HTML, SQL, 正则表达式......

    编程范式

    面向对象: 委托, 桥接, 修饰, MVC.......

    函数式编程: 修饰, 管道, 拼接

    逻辑推导式编程

    优化3

    继续优化. 看看是不是还有其他写法?答案是, 有的

    const actions = new Map([

    ['1', ['processing', 'IndexPage']],

    ['2', ['fail', 'FailPage']],

    ['3', ['fail', 'FailPage']],

    ['4', ['success', 'SuccessPage']],

    ['5', ['cancel', 'CancelPage']],

    ['default', ['other', 'Index']]

    ])

    const clickHandler = (status) => {

    let action = actions.get(status) || actions.get('default')

    sendLog(action[0])

    jumpTo(action[1])

    }

    新需求1

    有新的需求过来, 原先只是判断status的状态, 现在还需要判断用户的身份.

    const clickHandler = (status, identity) => {

    if(identity == 'guest') {

    if(status === 1) {

    // to do something

    } else if (status === 2) {

    // to do something

    } else if (status === 3) {

    // to do something

    } else if (status === 4) {

    // to do something

    } else if (status === 5) {

    // to do something

    } else {

    // to do something

    }

    } else if(identity == 'master') {

    if(status === 1) {

    // to do something

    } else if (status === 2) {

    // to do something

    } else if (status === 3) {

    // to do something

    } else if (status === 4) {

    // to do something

    } else if (status === 5) {

    // to do something

    } else {

    // to do something

    }

    }

    }

    又用了if / else来解决问题(里面的逻辑就没有写了, 因为代码太长了). 但当有两个层级的判断条件时, 如果还是用if / else, 代码量会加倍. 此时, 我们该如何写更优雅呢?

    const actions = {new Map([

    ['guest_1', () => {/* to do something */}],

    ['guest_2', () => {/* to do something */}],

    ['guest_3', () => {/* to do something */}],

    ['guest_4', () => {/* to do something */}],

    ['guest_5', () => {/* to do something */}],

    ['master_1', () => {/* to do something */}],

    ['master_2', () => {/* to do something */}],

    ['master_3', () => {/* to do something */}],

    ['master_4', () => {/* to do something */}],

    ['master_5', () => {/* to do something */}],

    ['default', () => {/* to do something */}],

    ])}

    上述代码的逻辑是:

    把两个条件拼接成字符串

    以拼接的条件字符串作为key, 以处理函数作为值的Map对象进行查找并执行

    当然, 也可以用Object对象来实现(这也是大家常用的)

    const actions = {

    'guest_1': () => {/* to do something */},

    'guest_2': () => {/* to do something */},

    'guest_3': () => {/* to do something */},

    'guest_4': () => {/* to do something */},

    'guest_5': () => {/* to do something */},

    'master_1': () => {/* to do something */},

    'master_2': () => {/* to do something */},

    'master_3': () => {/* to do something */},

    'master_4': () => {/* to do something */},

    'master_5': () => {/* to do something */},

    'default': () => {/* to do something */}

    }

    可能有些同学会觉得把查询条件拼接成字符串会不太优雅, 还有一种方案, 就是用Map对象, 以Object对象作为Key:

    const actions = new Map([

    [{identity: 'guest', status: 1}, () => {/* to do something */}],

    [{identity: 'guest', status: 2}, () => {/* to do something */}]

    [{identity: 'guest', status: 3}, () => {/* to do something */}]

    ])

    const clickHandler = (identity, status) {

    let action = [...actions].filter((key, value) => {key.identity === identity && key.status === status})

    action.forEach(([key, value]) => {value.call(this)})

    }

    这样会不会更优雅一点.

    Map与Object的区别: Map可以用任何类型的数据作为key

    新需求2

    假如在guest情况下, status 1~4 的处理逻辑是一样的, 最差的情况是:

    functionA(){

    // to do something

    }

    functionB(){

    // to do something

    }

    const actions = new Map([

    [{identity: 'guest', status: 1}, functionA],

    [{identity: 'guest', status: 2}, functionA],

    [{identity: 'guest', status: 3}, functionA],

    [{identity: 'guest', status: 4}, functionA],

    [{identity: 'guest', status: 5}, functionB],

    ])

    const clickHandler = (identity, status) {

    let action = [...actions].filter((key, value) => {key.identity === identity && key.status === status})

    action.forEach(([key, value]) => {value.call(this)})

    }

    这样写, 基本也满足需求了, 但重复的写4次functionA, 还是觉得有点不舒服(不过现在能够满足需求了, 好像也没什么关系了). 但如果identity的状态有3种, status的状态有30种呢? 难道......

    如果是此种情况, 也可以考虑用正则表达式, 如:

    functionA(){

    // to do something

    }

    functionB(){

    // to do something

    }

    const actions = new Map([

    [/^guest_[1-4]$/, functionA],

    [/^guest_5$/, functionA],

    ])

    const clickHandler = (identity, status) {

    let action = [...actions].filter((key, value) => {key.test(`${identity}_${status}`)})

    action.forEach(([key, value]) => {value.call(this)})

    }

    用Map的优势就很明显了, 可以用正则表达式类型作为key, 这样就可以满足更多的需求了.

    假如需求变成, 凡是guest的情况, 都要发送一个日志埋码, 不同的status的情况, 也要单独做处理. 那么我们可以考虑这样写:

    functionA(){

    // to do something

    }

    functionB(){

    // to do something

    }

    functionC(){

    // to do something

    }

    const actions = new Map([

    [/^guest_[1-4]$/, functionA],

    [/^guest_5$/, functionA],

    [/^guest_.$/, functionC],

    ])

    const clickHandler = (identity, status) {

    let action = [...actions].filter((key, value) => {key.test(`${identity}_${status}`)})

    action.forEach(([key, value]) => {value.call(this)})

    }

    利用数组循环的特性, 符合正则表达式条件的逻辑都会执行. 这样就可以同时执行公共逻辑和单独逻辑

    总结

    本文核心讲逻辑(Logic)和控制(Control)如何分离, 如果将所有的程序能够很好的分离, 那么代码的可维护性将会大大提高. 代码除了要运行, 可读性也是很重要的!

    本文转到: 一个多层 if / else 嵌套的代码重构案例

    展开全文
  • 小编整理了介绍python代码重构优化的一些方法,助你一臂之力。 编写干净的 Pythonic 代码就是尽可能使其易于理解,但又简洁。所以重构代码让代码简洁易理解是很有必要的。 本文重点是想跟大家探讨为什么这些重构是好...
  • 案例1:同一个类的两个函数含有相同的表达式 案例2:两个互为兄弟的子类含有相同的表达式 案例3:代码片段中语句有可能增删改,功能不变 02重复代码 什么是重复代码? 定义:在一个以上的地点看到相同或相似的代码...


    02重复代码

    什么是重复代码?

    定义:在一个以上的地点看到相同或相似的代码结构。
    影响:想要修改其中一段代码逻辑需要修改多次,易遗漏,难维护
    改进目标:消除重复,提升可维护性的目标。
    方法:提炼函数,移动语句,函数上移等重构方法。

    案例1:同一个类的两个函数含有相同的表达式

    /**
     * 计算水果总价(同一个类的两个函数含有相同的表达式)
     *
     * @since 2021-08-18
     */
    public class FruitsCost {
        public double computeMoneyWithoutPrivileges(String type, int numbers) {
            double prices;
            switch (type) {
                case "apple":
                    prices = 5.5;
                    break;
                case "banana":
                    prices = 4.0;
                    break;
                case "strawberry":
                    prices = 10.5;
                    break;
                default:
                    throw new IllegalArgumentException("Illegal type : " + type);
            }
            return prices * numbers;
        }
    
        public double computeMoneyWithPrivileges(String type, double numbers, double discount) {
            double prices;
            switch (type) {
                case "apple":
                    prices = 5.5;
                    break;
                case "banana":
                    prices = 4.0;
                    break;
                case "strawberry":
                    prices = 10.5;
                    break;
                default:
                    throw new IllegalArgumentException("Illegal type : " + type);
            }
            return prices * numbers * discount;
        }
    }
    

    代码背景:两个函数根据水果类型获得单价并计算水果费用;其中一个函数全价购买,一个函数打折购买;

    症状/问题:两个函数在获得水果单价的代码是一致的,如果其中一
    种水果单价出现变化,则需要同时修改两处

    重构方法
    我们重构的方法是这样,把相同部分的代码提取出来成一个方法,然后原代码处调用这个提取代码的方法即可。

    如果你用的是idea,可以这样做:
    选中重复的代码,按ctrl+shift+M(提取方法),出现一个窗口,我们可以修改访问级别,一般用private,毕竟是在类的内部使用,可以给方法命名,下面还有预览方法,确定好最后点refactor
    在这里插入图片描述
    然后他会提示其它方法的相同的代码(绿色部分),点replaces一起提取即可。
    在这里插入图片描述

    重构后

    public class FruitsCost {
        public double computeMoneyWithoutPrivileges(String type, int numbers){
            return getPrices(type) * numbers;
        }
    
        public double computeMoneyWithPrivileges(String type, double numbers, double discount){
            return getPrices(type) * numbers * discount;
        }
    
        private double getPrices(String type) {
            double prices;
            switch (type) {
                case "apple":
                    prices = 5.5;
                    break;
                case "banana":
                    prices = 4.0;
                    break;
                case "strawberry":
                    prices = 10.5;
                    break;
                default:
                    throw new IllegalArgumentException("Illegal type : " + type);
            }
            return prices;
        }
    }
    

    案例2:两个互为兄弟的子类含有相同的表达式

    /**
     * 水果利润(两个互为兄弟的子类含有相同的表达式)
     *
     * @since 2021-08-18
     */
    class Fruits {
        // 成本单价
        public double costPrices;
    
        // 出售单价
        public double prices;
    
        // 最小出货量
        public double minSaleableNum;
    }
    
    /**
     * 苹果利润(两个互为兄弟的子类含有相同的表达式)
     *
     * @since 2021-08-18
     */
    class Apple extends Fruits {
        public Apple(double costPrices, double prices, double minSaleableNum) {
            this.costPrices = costPrices;
            this.minSaleableNum = minSaleableNum;
            this.prices = prices;
        }
    
        public double profitMoney(int number) {
            return Math.max(0, number - minSaleableNum) * this.prices - this.costPrices * number;
        }
    }
    
    /**
     * 香蕉利润(两个互为兄弟的子类含有相同的表达式)
     *
     * @since 2021-08-18
     */
    class Banana extends Fruits {
        public Banana(double costPrices, double prices, double minSaleableNum) {
            this.costPrices = costPrices;
            this.minSaleableNum = minSaleableNum;
            this.prices = prices;
        }
    
        public double profitMoney(int number) {
            return Math.max(0, number - minSaleableNum) * this.prices - this.costPrices * number;
        }
    }
    

    代码背景:代码由水果父类,以及苹果香蕉两个子类组成。计算每种水果的销售利润。考虑运费、存储、破损等成本,计算毛利润时,需要从销量中减去最小出货量。

    症状:两个子类计算利润的方法完全一致,如果计算利润方式出现变化,则需要修改多个子类。

    重构方法
    我们可以把这些子类都有的方法提取,放到父类中。比如这个例子,把所有水果类中的profitMoney方法都提取到Fruits类中,只写一次。当我们添加新的水果子类时,不需要再写该方法;当计算利润方式发生变化时,我们只需要修改Fruits类中的方法即可,只需要修改一次;当其中某中水果有特殊的计算方式,我们只需要重写该子类的方法。这正好适应了面向对象继承和方法重写的特性。

    如果你用idea,你可以用快捷键来重构。
    将鼠标光标放到需要提取的方法上,按ctrl+shift+alt+T,或者右键到refator中,找到Pull Members Up,点击Refoctor,这样代码就提取到父类中了。
    在这里插入图片描述

    重构后代码
    把子类中的重复方法提取到父类中

    class Fruits {
        // 成本单价
        public double costPrices;
    
        // 出售单价
        public double prices;
    
        // 最小出货量
        public double minSaleableNum;
    
        public double profitMoney(int number) {
            return Math.max(0, number - minSaleableNum) * this.prices - this.costPrices * number;
        }
    }
    

    案例3:代码片段中语句有可能增删改,功能不变

    /**
     * 月份判断(代码片段中语句有可能增删改,功能不变)
     *
     * @since 2021-08-18
     */
    class MonthJudgement {
        public boolean judgeMonth() {
            Long timeStamp = System.currentTimeMillis();  // 获取当前时间戳
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String date = sdf.format(new Date(Long.parseLong(String.valueOf(timeStamp))));
            String month = date.split(" ")[0].split("-")[1];
            return "12".equals(month);
        }
    }
    
    /**
     * 年份判断(代码片段中语句有可能增删改,功能不变)
     *
     * @since 2021-08-18
     */
    class YearJudgement {
        public boolean judgeYear() {
            Long time = System.currentTimeMillis();  // 获取当前时间戳
            System.out.println("获得当前时间戳");
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String date = dateFormat.format(new Date(Long.parseLong(String.valueOf(time))));
            return date.startsWith("2021");
        }
    }
    

    代码背景
    重复代码出现在不同的类中。代码逻辑不完全一致,变量名不同分别为time和timeState, judgeYear多 了一条打印语句。

    症状
    两个类中函数judgeMonth和judgeYear函数逻辑基本上是一致,只是个别不相同的地方,如果修改时间格式,需要同时修改两处。

    重构方法
    把鼠标放在代码上,按ctrl+shift+上/下,可以移动语句,在方法上可以调动位置。注意你需要先确认这样不会改变业务逻辑,才可进行。然后才可以提取相同的代码。还可以搬移函数,放到其他的类中,如果使用快捷键(F6),需要先将抽取出来的方法改为静态。
    重构后代码

    /**
     * 日期转换
     *
     * @since 2021-08-18
     */
    public class DateFormatter {
        public static String getDate() {
            Long timeStamp = System.currentTimeMillis();  // 获取当前时间戳
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            return sdf.format(new Date(Long.parseLong(String.valueOf(timeStamp))));
        }
    }
    
    /**
     * 月份判断(代码片段中语句有可能增删改,功能不变)
     *
     * @since 2021-08-18
     */
    class MonthJudgement {
        public boolean judgeMonth() {
            String date = DateFormatter.getDate();
            String month = date.split(" ")[0].split("-")[1];
            return "12".equals(month);
        }
    }
    
    /**
     * 年份判断(代码片段中语句有可能增删改,功能不变)
     *
     * @since 2021-08-18
     */
    class YearJudgement {
        public boolean judgeYear() {
            System.out.println("获得当前时间戳");
            String date = DateFormatter.getDate();
            return date.startsWith("2021");
        }
    }
    
    
    展开全文
  • 在《The Pragmatic Programmer: From Journeyman to Master》(中文译名为《程序员修炼之道--从小工到专家》)Tip25 “怎样配平资源“中有一个重构代码的经典案例,现转录如下: 提示35 Finish What You Start ...

         在《The Pragmatic Programmer: From Journeyman to Master》(中文译名为《程序员修炼之道--从小工到专家》)Tip25 “怎样配平资源“中有一个重构代码的经典案例,现转录如下:

              提示35

             Finish What You Start

             要有始有终

          在大多数情况下这条提示都很容易应用。它只是意味着,分配某项资源的例程或对象应该负责解除该资源的分配。让我们通过一个糟糕的代码例子来看一看该提示的应用方式——这是一个打开文件、从中读取消费者信息、更新某个字段、然后写回结果的应用。我们去除了其中的错误处理代码,以让例子更清晰:

          void readCustormer(const char *fName, Customer  *cRec) {

        cFile = fopen(fName, "r+");

        fread(cRec, sizeof(*cRec), 1, cFile);

         }

         void writeCustomer(Customer  *cRect) {

        rewind(cFile);

        fwrite (cRec, sizeof(*cRec), 1, cFile);

        fclose(cFile);

      }

        void updateCustomer(const char *fName, double newBalance) {

        Customer cRec;

        readCustomer (fName, &CRec);

        cRec.balance = newBalance;

        writeCustomer(&cRec);

        } 

        初看上去,例程updateCustomer相当好。它似乎实现了我们所需的逻辑——读取记录,更新余额,写回记录。但是,这样的整洁掩盖了一个重大的问题。例程readCustomer和writeCustomer紧密地耦合在一起——它们共享全局变量cFile。readCustomer打开文件,并把文件指针存储在cFile中,而writeCustomer使用所存储的指针在其结束时关闭文件。这个全局变量甚至没有出现在updateCustomer例程中。

        这为什么不好?让我们考虑一下,不走运的维护程序员被告知规范发生了变化——余额只应在新的值不为负时更新。她进入源码,改动updateCustomer:

     

      void updateCustomer(const char *fName, double newBalance) {

        Customer cRec;

        readCustomer (fName, &CRec);

        if (newBalance >= 0.0)  {

          cRec.balance = newBalance;

          writeCustomer(&cRec);

        }

        } 

        在测试时一切似乎都很好。但是,当代码投入实际工作,若干小时后它就崩溃了,抱怨说打开的文件太多。因为writeCustomer在有些情况下不会被调用,文件也就不会被关闭。

       这个问题的一个非常糟糕的解决方案是在updateCustomer中对该特殊情况进行处理:

        void  updateCustomer(const char *fName, double newBalance) {

        Customer cRec;

        readCustomer (fName, &CRec);

        if (newBalance >= 0.0)  {

          cRec.balance = newBalance;

          writeCustomer(&cRec);

        }

        else 

          fclose(cFile);

        } 

          这可以修正问题——不管新的余额是多少,文件现在都会被关闭——但这样的修正意味着三个例程通过全局的cFile耦合在一起。我们在掉进陷阱,如果我们继续沿着这一方向前进,事情就会开始迅速变糟。

          要有始有终这一提示告诉我们,分配资源的例程也应该释放它。通过稍稍重构代码,我们可以在此应用该提示:

        void readCustomer(FILE *cFile, Customer *cRec) {

        fread(cRec, sizeof(*cRec), 1, cFile);

       }

       void  writeCustomer(FILE *cFile, Customer *cRec) {

        rewind(cFile);

        fwrite(cRec, sizeof(*cRec), 1, cFile);

       }

       void updateCustomer(const char *fName, double newBalance) {

        FILE *cFile;

        Customer  cRec;

     

         cFile = fopen(fName, "r+");

         readCustomer(cFile, &cRec);

           if (newBalance >= 0.0) {

          cRec.balance = newBalance;

          writeCustomer(cFile, &cRec);

        }

        fclose(cFile);

     }

        现在updateCustomer例程承担了关于该文件的所有责任。它打开文件并(有始有终地)在退出前关闭它。例程配平了对文件的使用:打开和关闭在同一个地方,而且显然每一次打开都有对应的关闭。重构还移除了丑陋的全局变量。

        由上文可见,重构时遵循一些原则是很重要的。

     

    转载于:https://www.cnblogs.com/yangjd/p/10711309.html

    展开全文
  • 目前项目代码的规模已经达到100多万行,负责项目开发和维护是由同一个团对来承担,其中的开发和设计人员有10人,这些是项目的基本情况。项目存在的问题:1、维护工作量很大,这占用了差不多40%左右的时间,这
  • 重构是在不改变软件可观察行为的前提下改善其内部结构 书中的案例如下: 以一个影片出租店用的程序,计算每位顾客的消费金额并打印详单。输入条件:顾客租了那些影片、租期多长;输出:费用根据租赁时间和影片类型...
  • Java 代码重构实例

    2011-03-20 10:06:02
    Java 代码 重构 实例 指南 ,欢迎下载
  • 附件是自己在阅读重构 改善既有代码结构的设计第一章时整理的思路,跟随Martin Fowler成为攻城狮是不错的,提升专业编码能力
  • 微信小程序高级开发与应用视频教程 微信小程序高阶组件与代码重构开发案例课程
  • 附件是自己在学习《重构 改善既有代码的设计》时所用到到的第一章代码和pdf,希望能够帮助广大的攻城狮
  • 2.为何重构2.1「重构」改进软件设计同样完成一件事,设计不良的程序往往需要更多代码,这常常是因为代码在不同的地方使用完全相同的语句做同样的事。因此改进设计的一个重要方向就是消除重复代码(DuplicateCode)...
  • 无论做什么事情呢,都要善始善终呢。前边连续发表了5篇关于重构的博客,其中分门别类的介绍了一些重构手法。今天的这篇博客就使用一个完整的...首先会给出需要重构代码,然后对其进行分析,然后对症下药,使用之前我
  • 2,8阅读第一章 第一个案例在此案例中使用了,方法的提取(extract method),方法的移动(move method),临时变量的清除,变量及函数名重构,switch类型重构(replace type code with state/strategy)等。重构使得代码...
  • java代码重构经验总结

    2009-07-30 11:12:56
    讲述了java代码重构总结 规范代码,有必要好好学习
  • 程序员必懂的代码重构(理论篇)一文介绍了代码重构是什么、常用的重构手法和代码中的“坏味道”。But talk is cheap. Show me the code,本文将从实战的角度来谈谈代码重构,共分为:题目、初步解法、重构实战和...
  • java重复代码重构_重构重复代码

    千次阅读 2020-08-29 18:37:48
    java重复代码重构As a software engineer working on a large project, you’ll likely be asked to do cleanup work on the code to make it more readable and more maintainable. There are several different ...
  • 代码重构之神秘命名

    多人点赞 热门讨论 2022-04-24 17:53:02
    聊聊代码中命令的重构手段
  • 1. 前言 重构,可以理解为一种帮助你改进已有代码设计的一种方法。若直接对这种方法下一个定义,那么很...所以,以一个简单案例入手,帮助我们熟悉一般简单场景重构的手法,然后一步步组合变化,去满足我们对大型...
  • 第1章 重构,第一个案例 1 1.1 起点 1 1.2 重构的第一步 7 1.3 分解并重组statement() 8 1.4 运用多态取代与价格相关的条件逻辑 34 1.5 结语 52 第2章 重构原则 53 2.1 何谓重构 53 2.2 为何重构 ...
  • 一、课程介绍:软件重构面临的背景都是相似的,程序员们为了快速完成需求和上线而写出了最基本的代码。然后在功能的不断扩充过程中,以打补丁的方式对代码进行扩充,中间还会面临着开发人员的变更和离职。逐渐地,...
  • 第1章 重构,第一个案例 1.1 起点 1.2 重构的第一步 1.3 分解并重组statement() 1.4 运用多态取代与价格相关的条件逻辑 1.5 结语 第2章 重构原则 2.1 何谓重构 2.2 为何重构 2.3 何时重构 2.4 怎么对经理说...
  • 针对TTC 2015 Java重构案例的VIATRA解决方案。 专案 该解决方案包含以下项目,每个项目都以hu.bme.mit.ttc.refactoring.开始hu.bme.mit.ttc.refactoring. 字首: model :包含案例中提供的类型图EMF模型以及我们...
  • 如果其他块重构 使用嵌套的if / else代码重构业务逻辑 该存储库随附了一系列有关如何重构业务逻辑的博客文章。 它旨在为我的有关重构的博客文章提供可读性帮助。
  • 第1章 重构,第一个案例 1.1 起点 1.2 重构的第一步 1.3 分解并重组Statemen 1.4 运用多态取代与价格相关的条件逻辑 1.5 结语 第2章 重构原则 2.1 何谓重构 2.2 为何重构 2.3 何时重构 2.4 怎么对经理说 2.5 重构的...
  • 主要对下面的七块进行分析编码格式规范代码重复代码覆盖率依赖项分析复杂度监控Java模拟技术代码评审和重构接下来的使用Eclipse插件来揭示这些分析领域:编码格式规范:codeStyle和CheckStyle代码重复:PMD的CPD代码...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 32,332
精华内容 12,932
关键字:

代码重构案例