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

copy-pase代码意味着你违法了不重复自己的原则(DRY原则).

而一旦你在你的方法中或者方法直接开始了copy-past,那么久意味着你的代码需要Extract Method. 恩在文章(1)(2)中介绍了部分的重构方法.

在提取放置之后呢,还可以根据情况利用Move Method重构手法,将其搬移到一个类中,然后在原来的调用处转为对该类方法的调用。或者利用Replace Method with Method Object,将这些职责封装为专有的类。关于Move Method重构手法  和  Replace Method with Method Object  会在 文章<从文章"避免复制与粘贴"到文章"Move Method"的反思>系列中自我理解.这里就先放一放.

这里呢牛人举了一个自己的实际的工作的例子来说明如何避免的copy-past.我讲理解性的描述一下他的过程

首先他有一个a 类 ,其中有个私有方法是设置参数变量unit的单位是rmb还是dollar. 然后这个方法被他的另一个函数creatUnit调用

class a

{

private void setUnitType( Unit unit)

  {

string type = "rmb";

     String moneyType = resource.getMoneyType();

if (moneyType.toLowerCase().equals(type)){

unit.setReportType(Unit.china_money);

else {

unit.setReportType(Unit.usa_money);

}

  }

protected void creatUnit()

{

      Unit unit;

unit.setCreditAmount = 100;

setUnitType( unit);

}

}

但是呢,悲剧的是他发现在b类中的某个函数也需要给Unit对象设置单位

class b

{

protected void changeUnit()

{

Unit unit;

      //需要调用一个给Unit设置单位的函数

}

}

我发现在b类中同样需要设置unit的类型。然而,setUnitType()方法却被定义为a的私有方法,无法被b对象调用。最简单的做法是采用复制的方式,将这段代码复制到b中。好了,如果此时我们不能忍住copy-paste的简便所带来的诱惑,或许就会陷入重复的泥沼了。Copy的动作绝对应该鸣起刺耳的警声。我们需要对这一做法保持足够的警惕。

然后呢..大牛就干了之下的事情

在他看了呢setUnitType干的事情无法就是给UnitType的对象赋值单位..因为他的UnitType中已经有了set和get方法,他只要再次在unitType中写一个私有方法让get函数返回就可以了. {Move method 重构}

class Unit

{

public: setUnitType()

  {

  }

public: getUnitType()

{

return getUnitTypeByInfo();

}

private void getUnitTypeByInfo( Unit unit)  //由于从a挪到了unit类这里需要Rename Method以及Extract Method等重构手法。

  {

string type = "rmb";

     String moneyType = resource.getMoneyType();

if (moneyType.toLowerCase().equals(type)){

      self.type = Unit.china_money

else {

      self.type = Unit.usa_money

}

  }

}

这样的话类a改为

class a

{

protected void creatUnit()

{

      Unit unit;

unit.setCreditAmount = 100;

unit.setUnitType( unit.getUnitType() )

}

}

class b

{

protected void changeUnit()

{

Unit unit;

      unit.setUnitType( unit.getUnitType() )

}

}

由于大牛的例子比较繁琐,所以就用这个简化的有错误的例子来说明原理,心领意会即可..

简单的说就是a类的一个函数功能 和 b类的一个函数功能是一样的..那么你可以把a类的函数功能拷贝到b类中,但是这样的话就是copy-past.很不好.但是他发现a类的这个函数功能和b类的这个函数功能都是对c类对象的操作.所有他就想法设法的把这部分操作挪到了c类自身中进行..这样的话在a类和b类中仅仅调用c类的方法即可.而不用有两份相同的代码了.

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

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

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

  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. 基于Unity3D的AOP使用思路

    考虑到AOP的特性,并参考Python的装饰模式(AOP类似),在做开发时,可以使用AOP的思想做一些工作上的简化(比如:运行时的Range属性.内存/存档加密属性等等). 但是AOP(使用的Post ...

  2. Jsp学习(2)

    Jsp的三大指令 (1).include 作用:相当于把当前页面去包含页面 语法: <%@include file="/common/test.jsp" %> 实例如下 ...

  3. java +bootstrap table 完整例子

    需求:现在常用的table 插件很多, 比如 jquey datatables ,不过操作挺 麻烦, 看到推荐的bootstrap 自带的 table,就用到项目来,先看效果:

  4. 3.3FactoryMethod——工厂方法

    意图: 定义一个用于创建对象的接口,让子类决定实例化哪一个类.FactoryMethod使一个类的实例化延迟到其子类. 其实在抽象工厂模式中,经过改进后的模式就是工厂方法模式,所以不多说了,上UML图 ...

  5. c# 请问如何将四个RadioButton分成两组?

    WinForm 只要放在同一个容器中的RadioButton 就自动互斥 创建两个panel容器,分别放两个RadioButton 就是两组了

  6. gdb调试运行时的程序小技巧

    使用gdb调试运行时的程序小技巧 标签: 未分类 gdb pstack | 发表时间:2012-10-15 04:32 | 作者:士豪 分享到: 出处:http://rdc.taobao.com/bl ...

  7. 聊聊 iOS 中的网络加密

    介绍下 公司的接口一般会两种协议的,一种HTTP,一种HTTPS的,HTTP 只要请求,服务器就会响应,如果我们不对请求和响应做出加密处理,所有信息都是会被检测劫持到的,是很不安全的,客户端加密可以使 ...

  8. oracle授权另外一个用户访问自己创建的数据对象

    oracle安装好之后,有一个默认的scott用户,该用户有一个默认的emp表,怎样让新创建的用户也能够访问这个表呢? 授权xiaoming这个用户访问emp表,但是xiaoming只有select权 ...

  9. springMVC+freemarker中Could not resolve view with name... 问题解决

    用到springMVC+freemarker,自己在做demo过程中报: 严重: Servlet.service() for servlet springmvc threw exception jav ...

  10. Android studio错误及解决办法

    错误: Cannot launch AVD in emulator. Output: emulator: ERROR: GPU emulation is disabled. Only screen s ...