![文件](https://i-blog.csdnimg.cn/blog_migrate/d41b7a303eccaa493e2e1b491b3a4485.png)
代码的气味及其重构对于新手来说可能是非常艰巨的,并且令人生畏。 因此,在本系列文章中,无论是经验丰富的Ruby开发人员还是初学者,我都试图使它们易于理解。
最后一篇文章提到了您应该注意的其他一些气味,并总结了这个小系列文章希望实现的目标。 最后的味道,如果您愿意...
主题
- 注释
- 回呼
- 坏名
- 混合蛋白
- 数据丛
最后的嗅觉
本系列的最后一篇文章类似奖金回合。 我想向您介绍更多的气味,这些气味可以快速解决,而不必大惊小怪。 可以这么说。 我认为,根据您从前几篇文章中学到的知识,大多数文章甚至都不需要代码示例来解决。
当您打开一本有关重构的书时,您会轻易发现比我们所讨论的更多的气味。 但是,有了这些重要的工具,您将做好应对这些问题的充分准备。
注释
慷慨地应用评论很少是一个好主意-可能永远不会。 为什么不? 因为这可能表明您的设计并不代表自己。 这意味着您的代码可能很难理解,需要字面解释。
首先,谁想要遍历代码中的文本,或更糟的是,遍历难以理解的代码。 如果两者都是常见现象,则将获得大奖。 那只是一种不好的形式,对跟随你的人不是很体贴,没有犯罪,受虐狂,想要折磨你未来的自我。
您想编写本身具有足够表现力的代码。 创建自己说话的类和方法。 在最好的情况下,他们讲的故事很容易理解。 这可能是关于配置的约定如此具有影响力的原因之一。 当然,重塑方向有时是提高您的理解和探索新领域的一个好习惯,但是在快节奏的开发环境中,您的同事正在寻求清晰度和快速导航-不仅在文件中,而且在您创建的思维导图中在您的代码中。
我不想进入一个全新的话题,但命名在所有这些中都起着重要作用。 代码中过多的注释会与良好的命名习惯和约定相抵触。 别误会我的意思,添加注释很好-只需停留在“照亮”您的代码的路径上,而不用分心。 注释当然不应该是聪明的代码的说明,因为您想炫耀,所以您通常可以解密这些代码。 如果您按照自己的方式使方法保持简单,并考虑周全地命名,那么您几乎不需要在代码之间编写整本小说。
远离以下内容:
- 待办事项清单
- 无效代码已注释掉
- 方法主体中的注释
- 每种方法有多个注释
通过提取方法划分方法的各个部分,并为方法的这一部分命名以告诉我们有关其职责的方法,而不是使所有细节杂乱无章地了解方法主体内部的情况,这也很有用。
def create_new_agent
...
end
...
# create new agent
visit root_path
click_on 'Create Agent'
fill_in 'Agent Name', with: 'Jinx'
fill_in 'Email', with: 'jinx@nsa.com'
fill_in 'Password', with: 'secretphrase'
click_button 'Submit'
...
什么更容易阅读? 当然没事! 通过提取的方法正确命名事物,使用您获得的免费里程。 它使您的代码变得更聪明,更容易理解,当然,如果再使用,再加上在一个地方进行重构的好处。 我敢打赌,这将大大减少您的评论。
回呼
这很简单。 不要使用与持久性逻辑无关的回调! 您的对象具有持久性生命周期(可以这么说,可以创建,保存和删除对象),并且您不希望通过其他行为(例如类的业务逻辑)来“污染”该逻辑。
保持简单,还记得吗? 应避免的典型示例是发送电子邮件,处理付款和付款。 为什么? 因为调试和重构代码应尽可能简单,并且混乱的回调具有干扰这些计划的声誉。 回调使将水弄得浑浊并多次在脚上开枪本身太容易了。
关于回调的另一个问题是,它们可以在#save
或#create
类的方法中隐藏业务逻辑的实现。 因此,不要因为看起来方便而懒惰并滥用它们!
当然,最大的担忧是担忧的耦合。 例如,为什么要让SpectreAgent
的创建方法处理#mission_assignment
或其他内容的传递? 通常,仅仅因为我们可以轻松地做到这一点,并不意味着我们应该这样做。 这是保证等待发生的事情。 该解决方案实际上非常简单。 如果回调的行为与持久性无关,则只需为其创建另一个方法即可。
坏名
错误的命名选择会带来严重的后果。 实际上,如果您将来不得不重新查看那段代码,那是在浪费别人的时间,甚至浪费您自己的时间。 您编写的代码是一组指令,供您和其他人阅读,因此,纯粹的逻辑,超级平庸,过于机灵或更糟的是,一种简单的惰性命名方法是您可能会遗忘的最糟糕的事情之一。 旨在通过提供更好的名称来使您的代码更易于理解。
清晰胜过虚假的聪明或不必要的简洁,在一周的任何一天都可以做到! 努力命名方法,变量和类,以使其易于遵循某种线程。
我不想说你应该以讲故事为目标,但是如果可以的话,那就去做吧! 机器不是需要“读取”您的代码的机器,它当然是由它们运行的。 也许这就是为什么“软件作家”这个术语最近在我身上越来越流行的原因之一。 我并不是说应该减少工程方面的内容,但是编写软件不仅仅是为机器编写毫无生气的指令-至少是优雅且激发使用乐趣的软件。
如果事实证明这比您想象的要困难得多,请不要惊慌。 命名非常困难!
混合蛋白
Mixins有异味吗? 好吧,假设它们可能很臭。 通过Mixins进行多重继承可能会很有用,但是有几件事使它们的作用不如开始使用OOP时所想的那样:
- 他们很难测试。
- 他们不能拥有自己的状态。
- 他们会“污染”命名空间。
- 由于功能是混合在一起的,因此并非总是很清楚。
- 它们会极大地增加类的大小或方法的数量。 小班规则,还记得吗?
我建议您阅读“关于继承的构成 ”的内容。 其要点是,您应该更多地依赖于自己单独构造的类的重用,而不是继承或子类化。 Mixins是一种继承形式,可以很好地利用它,但是您也应该对此有所怀疑。
数据丛
注意将相同的多个参数重复传递到您的方法中。 这通常表明它们之间的关系可以提取到自己的类中,从而可以通过减小参数的大小来极大地简化为这些方法提供数据的过程。 但是,是否值得引入新的依赖关系是您必须权衡的。
这种气味是我们可以更好地处理的另一种形式的细微重复。 一个很好的例子是传递一长串组成地址和信用卡信息的参数。 为什么不将所有这些都打包在一个现有的类中,或者不首先提取一个新的类并传递地址和信用卡对象呢? 考虑它的另一种方法是使用范围对象而不是起点和终点。 如果您的实例变量恰好适合该气味,则值得考虑提取一个类。 在其他情况下, 参数对象可能提供相同的抽象质量。
您将知道,如果您的系统更易于理解,并且发现了可以封装到一个对象中的新概念(例如信用卡),您将取得不小的成就。
最后的想法
恭喜你! 您已经大大提高了OOP技能! 老板状态正在接近。 不,真的,如果您对这整个话题还比较陌生,那就太好了!
作为最后的建议,我希望您能拿走一件事。 请记住,没有任何食谱会一直有效。 您将需要对每个问题进行不同的权衡,并经常混合使用不同的技术来满足您的需求。 另外,在您的职业生涯的其余部分,这很可能是您永远都不会停止的奋斗-尽管如此,我认为这是一场艰苦的斗争,这是一项富有创造力和挑战性的斗争。
这只是一个小小的猜测,但是我认为,如果您了解了我们涵盖的大多数主题,那么您将可以很好地编写其他开发人员喜欢发现的代码。 感谢您花时间阅读这个小系列,祝您好运成为快乐的黑客!
翻译自: https://code.tutsplus.com/articles/rubyrails-code-smell-basics-04--cms-25454