从文章"避免复制与粘贴"到文章"Extract Method"的反思(2)
好了.在上一篇里面讲了讲怎么把临时变量应该从函数里面剔除去.这个过程叫做从临时变量变成查询
那么接下来我们聊聊把代码提炼成函数,有叫做用函数对象取代函数
那么,问题来了:在函数中什么样的代码是需要被提炼出来单独成为函数的? 一般而言 代码里面的注释会指出 代码用途 和 实现手法直接的语义距离. 这里就暗示着如果代码前方有一行注释的话就以为这这里是需要提炼成函数的,并且可以在代码的基础上给这行代码命名(所以啊,这里的函数名很重要,因为他还承担了注释的作用,要让人看了这个函数名就能知道这个函数在干神马). 就算是一行代码,如何需要用注释来说明的话,也是有必要提炼成函数的.
----->
这里还有一些现场的规则来指导我们怎么做:
做法:
1、创造一个新函数,根据这个函数的意图对它命名(以它“做什么“命名,而不是以它“怎样做”命名)。
即使你想要提炼的代码非常简单,例如只是一条消息或一个函数调用,只要新函数的名称能够以更好方式昭示代码意图,你也应该提炼它。但如果你想不出一个更有意义的名称,就别动。
2、将提炼出的代码从源函数复制到新建的明白函数中。
3、仔细检查提炼出的代码,看看其中是否引用了“作用域限于源函数”的变量(包括局部变量和源函数参数)。
4、检查是否有“仅用于被提炼代码段”的临时变量。如果有,在目标函数中将它们声明为临时变量。
5、检查被提炼代码段,看看是否有任何局部变量的值被它改变。如果一个临时变量值被修改了,看看是否可以将被提炼代码处理为一个查询,并将结果赋值给修改变量。如果很难这样做,或如果被修改的变量不止一个,你就不能仅仅将这段代码原封不动提炼出来。你可能需要先使用Split Temporary Variable (分解临时变量),然后再尝试提炼。也可以使用 Replace Temp with Query (以查询取代临时变量)将临时变量消灭掉。
6、将被提炼代码段中需要读取的局部变量,当做参数传给目标函数。
7、处理完所有局部变量后,进行编译。
8、在源函数中,将被提炼代码段替换给对目标函数的调用。
如果你将如何临时变量移到目标函数中,请检查它们原本的声明式是否在被提炼代码段的外围。如果是,现在可以删除这些声明式了。
9、编译,测试。
函数中的条件表达式和循环也是提炼的信号. 循环没什么好言明的,应该讲循环和循环内部的代码提炼成一个函数. 接下来讲讲 条件表达式的提炼 官方叫做分解条件表达式
所谓的条件表达式就是下面的形式
if
.......
then
.......
else
......
分解条件表达式的动机:复杂的条件逻辑是程序复杂度上升点之一.因为你必须编写代码来判断不同的条件,而不同的条件下有做不同的事情.因为就会得到一个相当大的函数了.相当大的函数本身就意味着可读性的降低而条件逻辑则会使代码更难阅读。在带有复杂条件逻辑的函数中,代码(包括检查条件分支的代码和真正实现功能的代码)会告诉你发生的事,但常常让你弄不清为什么会发生这样的事
而我们分解条件表达式就是为了能够突出条件的逻辑结构.
看下面的例子吧:
------>
实际工作中,要一步一步的进行每一次的条件表达式的提炼,并在每次提炼之后编译并测试。这里需要注意的是,一般条件下我们程序员可能都不会去提炼条件,可能是因为这些条件非常短[指的是if(xxx)--->这里的xxx].但是尽管可能很短,很可能在代码意图和代码自身之间存在很大的差距.就像上面的例子 notSummer(data) 就要比 date.before(SUMMER_START) || date.after(SUMMER_END)这样的逻辑条件跟好的表达出代码的用途来,从而看起来就像是注释一样的清晰明了.
看完例子我们再回头聊一聊,条件表达式应该怎么具体操作:
1、将if段落提炼出来,构成一个独立函数。
2、将then和else段落提炼出来,各自构成一个独立函数。
好吧其实意思就是把if{代码1}then{代码2}else{代码3}中的代码1,代码2,代码3都最好搞成独立函数.而且看看if的条件是不是表达的很清晰,否则也搞成函数..
在牛人的关于提炼条件表达式的简洁中有下面的一句话
如果发现嵌套的条件逻辑,先观察是否可以使用Replace Nested Conditional with Guard Clauses (以卫语句取代嵌套条件表达式)。如果不行,才开始分解其中的每个条件。
针对这句话,在展开一个交流点
好吧,上面这句话中的什么叫做 嵌套的条件逻辑, 我承认我没弄明白. 不过没影响.这里要聊聊的是 以卫语句取代嵌套条件表达式 .还是看例子吧.有的时候文字看着晕乎,还不如直接看例子.再返回头看文字,就理解了..
一般而言条件表达式有两种形式
第一种:所有条件都是正常流程
例如:对人的身高的判断
if(中国人) ....
else if (美国人) ....
else if(欧洲人) .....
第二种:所有条件中只有一种正常形式,其他都是不常见或者异常的情况
例如: 对人的特征的判断
if(是人) ....
else if( 是动物) ... //异常
else if(是植物) .... //异常
对于第一种情况而言我们就要用正常的if then else
对于第二种情况而言就应该单独检查该条件,这种单独检查就被称为“卫语句”(guard clauses).意思是一个一个的用if拆开,而不要用if then else来搞了.. 看下面例子吧
例如:
解析来就进入主题,讲一讲 在代码开发中药避免复制和粘贴..看下一个篇幅吧
从文章"避免复制与粘贴"到文章"Extract Method"的反思(2)的更多相关文章
- 从文章"避免复制与粘贴"到文章"Extract Method"的反思(3)
在牛人的博客中提到了..如果你的代码可以copy-past的时候,那么久证明你的代码出现了重复.而这种重复仅仅是虚假的代码行的增加而不是像其他的代码复用那样降级成本. copy-pase代码意味着你违 ...
- 从文章"避免复制与粘贴"到文章"Extract Method"的反思(1)
看了一个比我牛的人的博客园的博文"避免复制和粘贴".里面提到了重构手法Extract Method. 所以又搜了一下Extract Method. 这里先自我理解Extract ...
- 如何在eclips下将一段代码抽取为方法Extract Method
最近读了读关于重构的文章,做了个小总结(在编程思想目录下<从文章"避免复制与粘贴"到文章"Extract Method"的反思 系列>). 然后因为 ...
- Laravel大型项目系列教程(四)显示文章列表和用户修改文章
小编心语:不知不觉已经第四部分了,非常感谢很多人给小编提的意见,改了很多bug,希望以后能继续帮小编找找茬~小编也不希望误导大家~这一节,主要讲的 是如何显示文章列表和让用户修改文章,小编预告一下(一 ...
- 用python+selenium登录cnblog后新增文章后再次删除该文章
目的:登录cnblog后新增文章后再次删除该文章并验证 代码如下: #coding: utf-8 from selenium import webdriver from time import sle ...
- dedecms文章页调用地址(当前文章URL)如何操作?
我们在建站时经常会在文末加一个本文地址,那么dedecms文章页如何调用当前文章URL呢?这样做的好处是增加文章的唯一标识,更进一步的做法是在head中加个cannacial标签,告诉搜索引擎url的 ...
- VS Extract Method
前言 看重构6.4Replace Temp with Query(以查询取代临时变量)中提到Replace Temp with Query往往是你运用Extract Method之前必不可少的一个步骤 ...
- 『重构--改善既有代码的设计』读书笔记----Extract Method
在编程中,比较忌讳的一件事情就是长函数.因为长函数代表了你这段代码不能很好的复用以及内部可能出现很多别的地方的重复代码,而且这段长函数内部的处理逻辑你也不能很好的看清楚.因此,今天重构第一个手法就是处 ...
- Refactoring #001 Extract Method
Example public void startup() { ServerSocket serverSocket = null; try { serverSocket = new ServerSoc ...
随机推荐
- 修改Unity脚本模板的方法合计
作为一个习惯于偷懒的程序,重复性的无聊内容是最让人无奈的事,就比如我们创建Unity脚本之后,需要手动调整生成的新脚本的格式.编码.内容:如果我们要编写的是编辑器或者服务器端脚本,需要修改的内容就会更 ...
- 利用Linq对集合元素合并、去重复处理
本文转载:http://www.cnblogs.com/yjmyzz/archive/2012/12/18/2823170.html 今天写代码时,需要对一个数组对象中按一定规则合并.去重处理,不想再 ...
- ios7新特性实践
一 iOS 7 新特性:视图控制器切换API 二 iOS 7系列译文:认识 TextKit 三 iOS 7系列译文:iOS7的多任务处理 四 iOS7 最佳实践:一个天气应用案例(上) 五 iOS7 ...
- 自定义toast功能
http://download.csdn.net/detail/caryt/8105031
- WCF探索之旅(一)——入门
背景 对于.NET程序员来说,假设你不知道WCF,那仅仅能说明一点:你还是个菜鸟. 曾经也用.NET做过几个系统,尤其做后面的系统的时候,心里就有点沾沾自喜了! 想着,.NET也就这点东西,我如今也能 ...
- JavaEE SSH框架整合(三) struts2 异常、http错误状态码处理
struts2的action可能出现訪问不到,或action报异常等情况,所以须要作一些处理,给用户一个友好的印象. 1. 异常处理 result声明在action中 <action name ...
- GUI之CCControlExtension
Introduction CCControl is inspired by the UIControl API class from the UIKit library of CocoaTouch. ...
- WPF中将DataGrid导出Excel
int number = 1; private void MenuItem_Click(object sender, RoutedEventArgs e) { #region string path ...
- nodejs 中koa框架下的微信公众号开发初始篇
最近在搞微信公众号开发,后端采用的是nodejs下的koa框架,初识后端的菜鸟,自己搞难度太大了,网上找了很多文章,采用的中间件大都是express框架下的,不过好在爬了许多坑之后总算看见点曙光了,遂 ...
- C# 分页
#region 分页 /// <summary> /// 分页 /// </summary> /// <param name="page">当前 ...