看了一个比我牛的人的博客园的博文"避免复制和粘贴".里面提到了重构手法Extract Method.  所以又搜了一下Extract Method. 这里先自我理解Extract Method 再自我反思博文"避免复制和粘贴"

先插一个题外话就是我们为啥要重构,否则真没看文章的必要了.....

1.更方便地添加新的功能,在添加新的功能之前,查看以前实现的相关代码,如果发现可以通过重构使得添加新功能更加简单,那就应该先重构。重构完成后,以前的测试用于保证重构没有破坏原来的功能。如通过重构,实现抽象工厂,添加新的子类时,就会很方便。达到事半功倍的效果。

2.改进已有代码的设计。经过多次的迭代以后,代码在不停地增加,原有设计无法再适应当前的代码,使得结构无序杂乱,重构可以改进设计,使得架构更加合理,更容易添加新的功能。

3.有助于更好的理解代码。

4.干净的代码可以使程序员有更好的心情。

Extract Method 的中文名叫做 "提炼函数". 那么在什么情况下需要提炼函数呢

第一个类型: 函数过长

函数过长的话有两种解决办法 驱除临时变量 和 提炼函数(提炼函数的话就是本文讲的,所有pass).所有先聊一聊 驱除临时变量

例子: 驱除临时变量的专业名词叫做  以查询取代临时变量

                        
   把从一行代码basePrice=_quantity*_itermPrice  变成了一个函数.然后在重构前的所有引用变量的地方让其调用函数.这么做的目的是:由于临时变量是暂时的仅在一个{}中有效,为了访问临时变量,就有用更多代码的趋势,而且如果改成是从临时变量替换成查询式,那么同一个类中所有函数都将可以获得这份信息。从而优化代码结构,显得更清晰;而且这种提炼方式是你的代码提炼成函数的基础,因为太多的临时变量导致你的代码要提炼成函数都会变得很难.这里需要注明的是这种方法最后适用于临时变量在函数中只是被赋值了一次的情况

那么应该如何进行替换呢(这里主要是指的是已经写完了代码,再进行重构)

第一步(1):找出只是被赋值一次的临时变量.

第二步(2): 把这个临时变量声明为final (int a = 1--> final int a = 1;)

第三步(3):编译(如果编译错误或者警告那就是这个变量被赋值了多次.final导致的.)

第四步(4):把临时变量等号右边的东西用提炼成一个独立的函数(首先将函数声明为private。日后你可能会发现还有好多地方需要使用它,那时放松对它的保护也很容易;确保提炼出的函数无任何副作用,即该函数不修改任何对象内容)

第五步(5):编译 确保没错

第六步(6):对该临时变量实施“内联临时变量”重构方法。

ps: 我们常常使用临时变量保存循环中的累加信息。在这种情况下,整个循环都可以被提炼为一个独立的函数,这可以减少原函数中几行循环逻辑代码。该手法的使用可能会让你担心性能上的问题。就像和其它性能问题一样,我们现在不用管它,因为十有八九根本没有造成任何影响。就算真的出问题了,你也可以在优化时期解决它。代码组织良好,你也会发现更有效的优化方案;如果没有进行重构,好的优化方案就可能与你失之交臂。

举一个例子我们希望把临时变量 basePrice  discountFactor 给去掉.那么首先在两个之前加上finanl然后编译确保没错误(即:仅被赋值一次)------>                                                                             然后一个一个的开始替换.首先替换basePrice .先把赋值动作右侧表达式提炼出来.然后编译测试,再开始使用内联临时变量。首先把临时变量basePrice的第一个引用点替换掉:编译、测试,然后进行下一个。由于下一个是最后一个引用点,所以把basePrice临时变量的声明式一并去掉:

------>------>                              完成basePrice之后,以类似的方法提炼出discountFactor():  你会发现,如果没有把临时变量basePrice替换为一个查询式,将多么难以提炼discountFactor()! (因为在discountFactor里面调用了basePrice() )  最终,getPrice()变成这样:

  ------->

在篇幅2里面就来谈一谈 把代码从函数中提炼出来组成函数,恩,有叫做 以函数对象取代函数.

从文章"避免复制与粘贴"到文章"Extract Method"的反思(1)的更多相关文章

  1. 从文章"避免复制与粘贴"到文章"Extract Method"的反思(3)

    在牛人的博客中提到了..如果你的代码可以copy-past的时候,那么久证明你的代码出现了重复.而这种重复仅仅是虚假的代码行的增加而不是像其他的代码复用那样降级成本. copy-pase代码意味着你违 ...

  2. 从文章"避免复制与粘贴"到文章"Extract Method"的反思(2)

    好了.在上一篇里面讲了讲怎么把临时变量应该从函数里面剔除去.这个过程叫做从临时变量变成查询 那么接下来我们聊聊把代码提炼成函数,有叫做用函数对象取代函数 那么,问题来了:在函数中什么样的代码是需要被提 ...

  3. 如何在eclips下将一段代码抽取为方法Extract Method

    最近读了读关于重构的文章,做了个小总结(在编程思想目录下<从文章"避免复制与粘贴"到文章"Extract Method"的反思 系列>). 然后因为 ...

  4. Laravel大型项目系列教程(四)显示文章列表和用户修改文章

    小编心语:不知不觉已经第四部分了,非常感谢很多人给小编提的意见,改了很多bug,希望以后能继续帮小编找找茬~小编也不希望误导大家~这一节,主要讲的 是如何显示文章列表和让用户修改文章,小编预告一下(一 ...

  5. 用python+selenium登录cnblog后新增文章后再次删除该文章

    目的:登录cnblog后新增文章后再次删除该文章并验证 代码如下: #coding: utf-8 from selenium import webdriver from time import sle ...

  6. dedecms文章页调用地址(当前文章URL)如何操作?

    我们在建站时经常会在文末加一个本文地址,那么dedecms文章页如何调用当前文章URL呢?这样做的好处是增加文章的唯一标识,更进一步的做法是在head中加个cannacial标签,告诉搜索引擎url的 ...

  7. VS Extract Method

    前言 看重构6.4Replace Temp with Query(以查询取代临时变量)中提到Replace Temp with Query往往是你运用Extract Method之前必不可少的一个步骤 ...

  8. 『重构--改善既有代码的设计』读书笔记----Extract Method

    在编程中,比较忌讳的一件事情就是长函数.因为长函数代表了你这段代码不能很好的复用以及内部可能出现很多别的地方的重复代码,而且这段长函数内部的处理逻辑你也不能很好的看清楚.因此,今天重构第一个手法就是处 ...

  9. Refactoring #001 Extract Method

    Example public void startup() { ServerSocket serverSocket = null; try { serverSocket = new ServerSoc ...

随机推荐

  1. Android中使EditText失去焦点,edittext禁止弹出键盘[转]

    转自http://www.cnblogs.com/yejiurui/archive/2013/01/02/2841945.html 在我们的应用中,有时候一进入一个页面, EditText默认就会自动 ...

  2. 模仿微信&quot;转你妹&quot;游戏

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  3. JVM经常使用的调优參数

    -Xms512m -Xmx1024m -XX:MaxPermSize=1204m -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled -XX:+ ...

  4. 最简单的基于FFMPEG的封装格式转换器(无编解码)

    本文介绍一个基于FFMPEG的封装格式转换器.所谓的封装格式转换,就是在AVI,FLV,MKV,MP4这些格式之间转换(相应.avi,.flv,.mkv,.mp4文件).须要注意的是,本程序并不进行视 ...

  5. [Webpack 2] Chunking common modules from multiple apps with the Webpack CommonsChunkPlugin

    If you have a multi-page application (as opposed to a single page app), you’re likely sharing module ...

  6. [TypeScript] Installing TypeScript and Running the TypeScript Compiler (tsc)

    This lesson shows you how to install TypeScript and run the TypeScript compiler against a .ts file f ...

  7. android intent 隐式意图和显示意图(activity跳转)

    android中的意图有显示意图和隐式意图两种, 显示意图要求必须知道被激活组件的包和class 隐式意图只需要知道跳转activity的动作和数据,就可以激活对应的组件 A 主activity  B ...

  8. 《细说 new与 malloc 的 10 点区别》

    http://www.jobbole.com/members/melonstreet/

  9. Linux Shell删除某一个目录下的所有文件夹(保留其他文件)

    #!/bin/bash direc=$(pwd) for dir2del in $direc/* ; do if [ -d $dir2del ]; then rm -rf $dir2del fi do ...

  10. Oracle存储过程中不支持DML语言的解决方法(针对遇见的DROP关键字)

    ---存储过程中的原语句: ---删除表 DROP TABLE A_NEWTDDATA; --报错 经查询:存储过程不支持DML语言: 解决方法: execute immediate 'DROP TA ...