如何摆脱工具类

标签: 摆脱 工具 | 发表时间:2014-06-11 18:16 | 作者:
出处:http://news.cnblogs.com/

英文原文: How to get rid of helper and utils classes

无论是进行代码 review 还是紧急编码调整,你总会发现:你又搞出了一个帮助类(helper class)。代码运行一切正常,进度又必须跟上,发布任务一个接一个,因此那个帮助类逐渐变成了一个提供了很多静态(static)方法的“怪兽类”(monster class),在它的 utils 包内不受控制地增长。utils 包长久以来就是一个技术争议的荒蛮之地,面向对象设计理念连半步都不敢踏入。“工具类是功能集中,并且逻辑毫不重复(Do not repeat yourself)” 一些开发人员会这样喊道 ,通常就是他们编写了这些工具类。因为所有都是静态的,所以它很快 - 团队里面的另外一些人这样说,也许就是是添加另外一些静态方法的人。它很容易使用,我们使这些代码很简洁 — 你可以在这个空间内听到这样的言论,但这又是 另外一个对 KISS 的误解了

我们会争论到:通常帮助类和工具类都很简单,特别是当我们不能修改新功能的目标类(例如外部依赖库)或我们不能找到使用的目标(不清晰的领域模型,PoC,需求缺失),或者我们只是不想去找它(懒,这也是帮助类的最主要原因)。但是最大的问题在于这很明显不是面向对象的解决方案,并且随着时间的推移(缺少团队沟通,资源重用,快速修复和一些其他的东西)它会导致一些包含无尽静态方法的容器和令人头疼的维护(你想要做到 DRY,但你却是用 10 个方法来提供几乎相同的功能,尽管不是完全一样;你想要快速,但你现在不能方便地添加一个 cache 机制到那个静态类中或者你遇到了并发的麻烦;你想使事情变得简单,但现在你的 IDE 提供了一长列的各种各样的方法,这并不能简化你的工作)。但不要担心,我们会尝试着去解决它。

让我们来重构帮助类

首先,我们需要定义我们的问题:一个只提供静态方法的无状态类(有 Helper 或 Utils 后缀),它没有明确的职责,在项目中也不会被初始化为对象。

接着,我们需要一个几乎明确的方案来解决问题。这几乎就代表了例外和项目特性:最后的决定当然是根据具体的情况来了,任何被称为通用解决方案的基本上都可以忽略。我们最后需要分析一下给出的类,尝试着:

  • 找到一个确定静态方法从属的目标类
  • 或找到这个类实际提供的目标业务实体,然后把它迁移到相关的组件,重命名并且删除静态方法(替换它们)
  • 或者通过面向对象方式添加一个提供一个或多个行为(之前存在的静态方法)新类。

上面的任何方案都可以提供一个更好的模型。然后我们再依据下面的步骤(假设根据下面的步骤进行项目重构):

  1. 为了使我们的任务简单些,我们删掉项目的帮助类中没用的方法(你的 IDE 将会帮你大忙)。
  2. 接下来我们把 class 定义为 final。你看到项目中有编译错误了吗?如果有,为什么帮助类或工具类需要被继承呢?你也许已经有一个目标:子类。如果子类是另外一个帮助类(真的吗?),把它和父类合并吧。
  3. 如果不存在,我们为该类添加一个私有构造函数。你看到项目中出现了编译错误了吗?那么肯定在哪个地方初始化了这个类,所以这并不是单纯的帮助类或者它没有被正确使用。看一下那些调用方,你会发现一个或一系列方法都可能属于这个目标类(或者实体)。
  4. 让我们通过一定规则类似的签名来分组类方法,将它们拆分到更小的帮助类中(从繁杂到有共性的方法,那个共性也许就是我们需要的目标实体了)。通常到了这一步,我们会从一个大的工具类向更轻量的帮助类过渡(提示:这时候不要害怕创建一个只有一个方法的类),同时我们的范围缩小了(从 ProjectUtilsCarHelperEngineHelperWheelHelper等等)。(好,你的代码难道看起来不是更简洁了吗?)
  5. 如果这些新类只有一个方法,我们需要看一下它的用途。如果我们只有一个调用者,那么恭喜你,那就是我们的目标类了!你可以把方法移到类中,作为 behavior 或私有方法(保持它的 static 标识或者利用内部状态)。这个帮助类就消失了。

  6. 我们目前得到的帮助类(但是它确实可以成为你的起点)确定了这些关联方法的一个通用状态。提示:看一下那些方法中的大部分通用参数(例如,所有方法都接收一个 Car对象),这表明,这些方法可能应该作为方法属于 Car类(或者扩展?封装类?)。否则,这些通用的参数应该是一个可以传给构造函数并且被所有(非静态和其他的)方法使用的类的属性,状态。那个属性应该会使你想起类的前缀,方法的归类可以使你想起一系列行为的类( CarValidatorCarReaderCarConverter等等)。那么这个帮助类又可以去掉了。

  7. 如果这堆方法根据可选的输入和一些相同输入参数来使用不同的参数,那么考虑通过使用建造者模式(Builder pattern)定义可变的接口来转换这个帮助类:从一系列类似 Helper.calculate (x)calculate (x, y)calculate (x, z)calculate (y, z)的静态方法我们可以简单地想到如 newBuilder () .with (x) .with (y) .calculate ()。帮助类会提供 behaviours,减少业务方法列表,并且提供更好的扩展性。调用方可以把它当作内部属性来重用或者在需要的时候再初始化。这个帮助类(我们所知的)又可以去掉了。
  8. 如果帮助类提供的方法确实是供不同的参数使用的(但,在这个时候,都是用于同一对象的),可以考虑使用命令模式(Command pattern):调用方实际上创建必须的命令(处理必须的输入和提供必要的操作),在确定的上下文情况下会有一个调用者进行执行。你也许可以获取到每个静态方法的命令实现,你的代码也从 Helper.calculate (x,y)calculate (z)变成了 invoker.calculate (new Action (x, y))。帮助类再见。

  9. 如果帮助类提供的方法接收相同的参数,但处理不同的逻辑,可以考虑使用策略模式( Strategy pattern):每一个静态方法都可以简单地变成一个策略实现,从而消除原来的帮助类(取而代之的是上下文组件)。

  10. 如果需要处理的多个静态方法涉及到一个类层次或一系列的组件,可以考虑使用访问者模式( Visitor pattern):你可以根据不同的访问方法得到几个访问者实现,这也许可以替换部分或所有之前存在的静态方法。
  11. 如果之前的情况都不符合你的情况,那可以使用三个最重要的指标:你的经验,你的项目能力和直觉。

总结

过程很简单,找到对的实体和合理的目标类或者通过一种采用面向对象设计的标准方法来重构给定的帮助类(但会在代码复杂度上有所增加,值得吗?)。过一下上面提到的场景列表,也许当你尝试理解怎么去实现重构时会有多于一个将会为你提供灵感;特定的限制也许会限制已确定的解决方案;复杂的静态方法和相关的流程也许需要几个重构的步骤,可以一直优化它直到得到可接受的结果。或者你可以选择在某种程度上以代码可读性和 简单性的名义来维持原来的帮助类(希望能满足上面至少 5 个步骤)。帮助类并不都是有害的,但绝大多数情况下你并不需要它们。

参考:  如休整脱离帮助类和工具类参考自我们的 JCG 成员 Antonio Di Matteo 重构的建议

翻译:  ImportNew.com 陈晓舜
译文链接:  http://www.importnew.com/11593.html

本文链接

相关 [摆脱 工具] 推荐:

如何摆脱工具类

- - 博客园_新闻
英文原文: How to get rid of helper and utils classes. 无论是进行代码 review 还是紧急编码调整,你总会发现:你又搞出了一个帮助类(helper class). 代码运行一切正常,进度又必须跟上,发布任务一个接一个,因此那个帮助类逐渐变成了一个提供了很多静态(static)方法的“怪兽类”(monster class),在它的 utils 包内不受控制地增长.

如何摆脱信息茧房?

- - 运营派
编辑导语:信息茧房是指人们关注的信息领域会习惯性地被自己的兴趣所引导,从而将自己的生活桎梏于像蚕茧一般的“茧房”中的现象. 现如今,人们的生活在信息茧房中,线下接触同一类圈子,线上大数据推送相类似的文章. 这不是一个好的现象,如何摆脱信息茧房,如何“破圈”,本篇文章作者将告诉你答案,快来阅读吧. “下次只能光看不点了, 我才夹一筷子,给我推送一桌子”.

USB OTG 3.0补充规范:摆脱PC直接互连

- Jerry - cnBeta.COM
USB 3.0推广集团今天公布了USB 3.0规范的补充标准“USB On-The-Go 3.0 and Embedded Host”(USB OTG 3.0与嵌入式主机),支持USB 3.0接口的便携式设备之间直接通信,而无需借助PC主机担任中间过渡角色.

Siri 将无处不在,未来 Apple TV 摆脱遥控器

- Yu - 爱范儿 · Beats of Bits
无疑,Siri 是苹果(Apple)这一年里最重要的发明之一,它(她. )的出现,它展现出来的智能,所带来的便利,让人不禁这么想:如果其它的设备有 Siri 功能就好了. 根据纽约时报的报道,一位熟知 Apple TV 项目的消息来源,称 Apple TV 将整合 Siri 功能. 如此一来,用户就可以摆脱布满按钮的遥控器,想让电视机做什么,只需要对它说出自己的想法.

Zynga推出自有门户 欲摆脱Facebook的影响

- - 行业资讯
   Zynga推出自有门户 欲摆脱Facebook的影响.   在一个巨大的战略十字路口,Zynga今天突然宣布,它将推出一个全新的Zynga.com门户网站,这样用户可以不通过访问Facebook便可玩社交游戏. 分析人士指出,此举将对社交游戏和社交网站有着巨大影响,因为Facebook的12%收入是来自Zynga,同时对于Zynga而言,它超过90%的收入都是来自Facebook.

摆脱各种会员卡,一张 AppCard 足矣

- - 爱范儿 · Beats of Bits
相信很多女性朋友的钱包里头一定装满了各种店面的会员卡和优惠券等. 有时候上街忘记带会员卡的时候,人们往往会懊悔不已. 以后, AppCard  将不再让这种场景出现. 只要记住自己的手机号,就可以随时享受多家店面的优惠. AppCard 虽然 2011 年就已经成立了,但是所受关注并不多. 据 TNW 的消息,因为获得 Google 执行董事长 Eric Schmid 旗下投资商和雅虎创始人杨致远的投资,AppCard 近日备受关注并成功融资了 650 万美元.

BitTorrent 开发出摆脱服务器的安全通信技术!

- - TECH2IPO创见
自从斯诺登揭露了美国国家安全局的监听项目后,如何使得线上的通信变得更加安全,就变成了当务之急. BitTorrent ,这种点对点的文件分享,多年来依赖于服务器处理,环节尽管易被攻击和侵入,但是就这么磕磕绊绊沿用下来了. 但是,现在基于 BitTorrent 开发出的技术,出现了更加先进的不依赖于服务器的通信方式:BitTorrent Chat.

IOGEAR的USB设备WIFI无线共享器,摆脱线缆烦恼

- emarine - Engadget 中国版
引用来源 | 此文章网址 | 转寄此文章 | 回应.

乙型肝炎病毒——何日摆脱萦绕国人的梦魇

- . - 牛博国际
长久以来,乙型肝炎病毒(HBV)一直如缠绕在国人身边阴魂不散的梦魇,无数人家因乙肝及其并发症负债累累、家破人亡;无数年轻人因为身带乙肝病毒而被就职单位拒之门外;无数父母因为孩子感染乙肝而内疚不已,在心中暗自流泪. 事实上,乙型肝炎病毒破坏的家庭恐怕已经难以用亿万来计数了. 截至2005年[1],估计全世界有3.5亿慢性乙型肝炎病毒携带者,有大约20亿人正在或曾经遭受乙肝病毒的感染.