资讯专栏INFORMATION COLUMN

重构-改善既有代码的设计(十)--简化函数调用

SQC / 2605人阅读

摘要:函数改名问题函数的名称未能揭示函数的用途。这些人甚至会在构造函数中使用设值函数。方法将构造函数替换为工厂函数。以上所说的情况,常会在返回迭代器或集合的函数身上发生。以异常取代错误码问题某个函数返回一个特定的代码,用以表示某种错误情况。

Rename Method 函数改名 问题

函数的名称未能揭示函数的用途。

方法

修改函数名称。

动机

好的函数需要有一个清晰的函数名。保证一看就懂

Add Parameter 添加参数 问题

某个函数需要从调用端得到更多信息。

方法

为此函数添加一个对象参数,让该对象带进函数所需信息。

动机

如果发现缺少参数,当然就需要添加参数。但是在添加之前,先思考是否一定要添加。或者实用参数对象

Remove Parameter 移除参数 问题

函数本体不再需要某个参数。

方法

将该参数去除。

动机

别人在调用的时候,面对这个无用的参数可能无所适从

Separate Query from Modifier 将查询函数和修改函数分离 问题

某个函数既返回对象状态值,又修改对象状态。

方法

建立2个不同的函数,其中一个负责查询,另一个负责修改。

动机

首先这个函数做了两件事,就很值得重构了。其次 不光要查询,还要修改。这个函数会成为bug之源。
考虑并发情况

Parameterize Method 令函数携带参数 问题

若干函数做了类似的工作,但在函数本体中却包含了不同的值。

方法

建立一个单一函数,以参数表达那些不同的值。

动机

你可能会发现这样的2个函数:它们做着类似的工作,但因少数几个值致使行为略为不同。这种情况下,你可以将这些各自分离的函数统一起来,并通过参数来处理那些变化,用以简化问题。这样的修改可以去除重复代码,并提高灵活性,因为你可以用这个参数处理更多的变化情况。

Replace Parameter with Explicit Methods 以明确函数取代参数 问题

你有一个函数,其中完全取决于参数值而采取不同行为。

方法

针对该参数的每个可能值,建立一个独立函数。

动机

(以明确函数取代参数)恰恰相反于 (令函数携带参数)。如果某个参数有多种可能的值,而函数内又以条件表达式检查这些参数值,并根据不同参数值做出不同的行为,那么就应该使用本项重构。

Preserve whole object 保持对象完整 问题

你从某个对象中取出若干值,将它们作为某一次函数调用时的参数。

方法

改为传递整个对象。

动机

有时候,你会将来自同一对象的若干项数据作为参数,传递给某个函数。这样做的问题在于:万一将来被调用函数需要新的数据项,你就必须查找并修改对此函数的所有调用。如果你把这些数据所属的整个对象传给函数,可以避免这种尴尬的处境,因为被调用函数可以向那个参数对象请求任何它想要的信息。不过事情总有2面:如果你传的是数值,被调用函数就只依赖于这些数值,而不依赖它们所属的对象。

Replace Parameter with Methods 以函数取代参数 问题

对象调用某个函数,并将所得结果作为参数,传递给另一个函数。而接受该参数的函数本身也能够调用前一个函数。

方法

让参数接受者去除该项参数,并直接调用前一个函数。

动机

如果函数可以通过其他途径获得参数值,那么它就不应该通过参数取得该值。过长的参数列会增加程序阅读者的理解难度,因此应该尽可能缩短参数列的长度。

Introduce Parameter Object 引入参数对象 问题

某些参数总是很自然地同时出现。

方法

以一个对象取代这些参数。

动机

本项重构还可以带给你更多好处。当你把这些参数组织到一起后,往往很快可以发现一些可被移至新建类的行为。通常,原本使用那些参数的函数对这一组参数会有一些共通的处理,如果将这些共通行为移到新对象中,你可以减少很多重复代码。

Remove setting Method 移除设置函数 问题

类中的某个字段应该在对象创建时被设值,然后就不再改变。

方法

去掉该字段的所有设值函数。

动机

如果你为某个字段提供了设值函数,这就暗示这个字段值可以被改变。如果你不希望在对象创建之后此字段还有机会被改变,那就不要为它提供设值函数。这样你的意图会更加清晰,并且可以排除其值被修改的可能性。
如果你保留了间接访问变量的方法,就可能经常有程序员盲目使用它们。这些人甚至会在构造函数中使用设值函数。

Hide Method 隐藏函数 问题

有一个函数,从来没有被其他任何类用到。

方法

将这个函数修改为private。

动机

重构往往促使你修改函数的可见度。提高函数可见度的情况很容易想象:另一个类需要用到某个函数,因此你必须提高该函数的可见度。但是要指出一个函数的可见度是否过高,就稍微困难一些。理想状态下,你可以使用工具检查所有函数,指出可被隐藏起来的函数。即使没有这样的工具,你也应该时常进行这样的检查。

   一种特别常见的情况是:当你面对一个过于丰富、提供了过多行为的接口时,就值得将非必要的取值函数和设值函数隐藏起来。尤其当你面对的是一个简单封装的数据容器时,情况更是如此。随着越来越多行为被放入这个类,你会发现许多设值/取值函数不再需要被公开,因此可以将它们隐藏起来。如果你把取值/设值函数设为private,然后在所有地方都直接访问变量,那就可以放心移除取值/设值函数了。
Replace Constructor with Factory Method 以工厂函数取代构造函数 问题

你希望在创建对象时不仅仅是做简单的建构动作。

方法

将构造函数替换为工厂函数。

动机

就是在派生子类的过程中以工厂函数取代类型码。你可能常常需要根据类型码创建相应的对象,现在,创建名单中还得加上子类,那些子类也是根据类型码来创建。然而由于构造函数只能返回单一类型的对象,因此你需要将构造函数替换为工厂函数。

   此外,如果构造函数的功能不能满足你的需要,也可以使用工厂函数代替它。工厂函数也是Change Value to Reference (将值对象改为引用对象)的基础。你也可以令你的工厂函数根据参数的个数和类型,选择不同的构建行为。

Encapsulate Downcast 封装向下转型 问题

某个函数返回的对象,需要由函数调用者执行向下转型(downcast)。

方法

将向下转型动作移到函数中。

动机

向下转型也许是无法避免的,但你仍然应该尽可能少做。如果你的某个函数返回一个值,并且你知道所返回的对象类型比函数签名所昭告的更特化,你便是在函数用户身上强加了非必要的工作。这种情况下你不应该要求用户承担向下转型的责任,应该尽量为他们提供准确的类型。
以上所说的情况,常会在返回迭代器或集合的函数身上发生。此时你就应该观察人们拿这个迭代器干什么用,然后针对性地提供专用函数。

Replace Error Code with Exception 以异常取代错误码 问题

某个函数返回一个特定的代码,用以表示某种错误情况。

方法

改用异常。

动机

可以使用更好的错误处理方式:异常。它清楚地将“普通程序”和“错误处理”分开了,这使得程序更容易理解:代码的可理解性应该是我们追求的目标。

Replace Exception with Test 以测试取代异常 问题

面对一个调用者可以预先检查的条件,你抛出一个异常。

方法

修改调用者,使它在调用函数之前先做检查。

动机

异常的出现是程序语言的一大进步。但是,就像许多好东西一样,异常会被滥用,从而变得不再让人愉快。“异常”只应该被用于异常的、罕见的行为,也就是那些产生意料之外的错误的行为,而不应该成为条件检查的替代品。如果你可以合理期望调用者在调用函数之前检查某个条件,那么就应该提供一个测试,而调用者应该使用它。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/71129.html

相关文章

  • 重构---改善既有代码设计》之简化条件表达式

    那有什么天生如此,只是我们天天坚持。 本篇文章主要讲解 《重构---改善既有代码的设计》 这本书中的 第九章简化条件表达式中 的知识点, Decompose Conditional(分解条件表达式) 问题:你有一个复杂的条件(if、then、else) 语句 解决:从if、then、else三个段落中分别提炼出独立函数 //重构前 if (date.before(SUMMER_START) |...

    Cheng_Gang 评论0 收藏0
  • 重构-改善既有代码设计(九)--简化条件表达式

    摘要:但条件逻辑也是不能忽视的分解条件表达式问题有一个复杂的条件语句。没什么说的动机重构代码就是错移除控制标志问题在一系列布尔表达式中,某个变量带有控制标记的作用方法以语句或语句取代控制标记动机控制标记大大降低了代码可读性。 前言 前面已经对类,方法,字段都进行了重构。貌似看起来很完整了。但条件逻辑也是不能忽视的 分解条件表达式 问题 有一个复杂的条件(if-then-else)语句。(判断...

    missonce 评论0 收藏0
  • Java学习路线总结,搬砖工逆袭Java架构师(全网最强)

    摘要:哪吒社区技能树打卡打卡贴函数式接口简介领域优质创作者哪吒公众号作者架构师奋斗者扫描主页左侧二维码,加入群聊,一起学习一起进步欢迎点赞收藏留言前情提要无意间听到领导们的谈话,现在公司的现状是码农太多,但能独立带队的人太少,简而言之,不缺干 ? 哪吒社区Java技能树打卡 【打卡贴 day2...

    Scorpion 评论0 收藏0
  • 读书笔记《重构 改善既有代码设计

    摘要:重构在不改变代码的外在的行为的前提下对代码进行修改最大限度的减少错误的几率本质上,就是代码写好之后修改它的设计。重构可以深入理解代码并且帮助找到。同时重构可以减少引入的机率,方便日后扩展。平行继承目的在于消除类之间的重复代码。 重构 (refactoring) 在不改变代码的外在的行为的前提下 对代码进行修改最大限度的减少错误的几率 本质上, 就是代码写好之后 修改它的设计。 1,书中...

    mdluo 评论0 收藏0
  • 重构---改善既有代码设计

    摘要:为何重构重构有四大好处重构改进软件设计如果没有重构,程序的设计会逐渐腐败变质。经常性的重构可以帮助维持自己该有的形态。你有一个大型函数,其中对局部变量的使用使你无法采用。将这个函数放进一个单独对象中,如此一来局部变量就成了对象内的字段。 哪有什么天生如此,只是我们天天坚持。 -Zhiyuan 国庆抽出时间来阅读这本从师傅那里借来的书,听说还是程序员的必读书籍。 关于书的高清下载连...

    baihe 评论0 收藏0

发表评论

0条评论

SQC

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<