技术控

    今日:102| 主题:49113
收藏本版 (1)
最新软件应用技术尽在掌握

[其他] Fundamental tensions in code smells

[复制链接]
深流Penetrasunny 发表于 2016-9-30 11:09:04
189 8

立即注册CoLaBug.com会员,免费获得投稿人的专业资料,享用更多功能,玩转个人品牌!

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
I recently saw a terrific talk by Sandi Metz at the Abstractions conference where she encouraged the audience to learn to identify the concrete code smells from Martin Fowler 's Refactoring . Two of the biggest takeaways I heard in the talk were that we as developers should be able to identify code smells by name, and also to identify and complete the prescribed refactorings to clean them up.
   Sandi also made a terrific, subtle, and often-missed point that I'd like to expand on here: code smells are pieces of code that we might want to refactor. For example, if a given smelly piece of code rarely needs to be changed or even read by the development team, there's little reason to burn time on refactoring that code. And it even goes a bit further: some code smells, like refactorings, are polar opposites of one another, such that the obvious refactoring of one smell can cause the other smell to surface.
  With refactoring, it's clear from the names of pairs like Extract Class and Inline Class, or Extract Method and Inline Method, that they are inverses of each other. Less clear, perhaps, are the tensions between smells.
  Feature Envy

   Feature Envy describes a situation where a given class uses mostly data and methods from some other class, instead of its own data and methods. In the following example, we could say that USContactFormatter envies the features of User :
  [code]class User
  attr_accessor :address_line_1, :address_line_2, :city, :state, :zipcode
end

class USContactFormatter
  def initialize(user)
    @user = user
  end

  def mailing_address
    [
     @user.address_line_1,
     @user.address_line_2,
     "[email protected]}, [email protected]} [email protected]}"
    ].compact.join("\n")
  end

  def phone_number
    @user.phone.gsub(/\D/, "")
  end
end[/code]  The problem, in principle, is that it can get unwieldy to always be sending messages to another object to do work, rather than just delegating the behavior to that object. Encapsulation and "Tell Don't Ask" are both relevant principles here.
  The typical refactoring for feature envy moves methods over to the class where they "belong" (the class that's the focus of the envy). In our case above, that might look like this:
  [code]class User
  attr_accessor :address_line_1, :address_line_2, :city, :state, :zipcode

  def mailing_address
    [
     address_line_1,
     address_line_2,
     "#{city}, #{state} #{zipcode}"
    ].compact.join("\n")
  end

  def phone_number
    phone.gsub(/\D/, "")
  end
end[/code]   And now nobody can accuse us of feature envy: we've got our behavior ( mailing_address and phone_number ) in the same class that's got the data.
  But I introduced this post with the idea that there would be tension, so how could the clear improvement above possibly cause issues?
  Large Class

  The trouble happens when a piece of data or behavior is important to a system. Addressing feature envy in the obvious way (as above) accrues methods on the class where that data lives. The more times you fix the feature envy, the bigger that class grows.
  To start, things might just look like this:
   
Fundamental tensions in code smells-1 (encouraged,prescribed,recently,concrete,audience)

  But as systems grow and important domain concepts congeal, it's common to end up with something like this:

Fundamental tensions in code smells-2 (encouraged,prescribed,recently,concrete,audience)

   And this is how projects end up with 2000-line User classes. Large Classes can be difficult to manage for a whole slew of reasons that have been well documented.
  What to do?

   We could sort of cheat by denormalizing the User state across multiple objects. This approach could work fine, especially if we're dealing in immutability as I always prefer. Meanwhile we've introduced complexity into the system, in the form of a Middle Man smell.
   Similar tradeoffs exist between the Message Chain and Large Class smells. And while I haven't enumerated more, I feel pretty confident that the two that occurred to me off the top of my head aren't the only two.
  I suspect we simply cannot write the perfect solution, even for this small problem space (not to mention entire systems). Does this mean that code smells are without merit? That we should just plug our noses and ignore them? That's certainly the easy way: just flip a coin and get on with it. But we wouldn't be doing our job if we decided to punt on hard decisions.
  When we decide to address a code smell, thinking about the tradeoffs can help us make better decisions. By understanding what problems we're trying to solve, and what problems we'll accept as a consequence of our decision, we'll be better equipped to solve the problems that code smells warn us about.
  And as systems evolve and grow over time, the tradeoffs behind our initial decisions change, which means we probably ought to revisit our decisions. As the saying goes:
     When the facts change, I change my mind. What do you do, sir?
   
       
  • John Maynard Keynes   

友荐云推荐




上一篇:Dynamically Generate SQL Server BCP Format Files
下一篇:一步一步搭建ReactNative开发环境
酷辣虫提示酷辣虫禁止发表任何与中华人民共和国法律有抵触的内容!所有内容由用户发布,并不代表酷辣虫的观点,酷辣虫无法对用户发布内容真实性提供任何的保证,请自行验证并承担风险与后果。如您有版权、违规等问题,请通过"联系我们"或"违规举报"告知我们处理。

lly3616 发表于 2016-9-30 12:59:00
沙发是我的,谁也不要抢!
回复 支持 反对

使用道具 举报

念桃 发表于 2016-9-30 13:31:04
大学就是大概学学!
回复 支持 反对

使用道具 举报

zjj6483 发表于 2016-10-1 05:19:03
世界末日我都挺过去了,看到深流Penetrasunny我才知道为什么上帝留我到现在!
回复 支持 反对

使用道具 举报

刘铭瑶 发表于 2016-10-2 07:57:34
LZ帖子不给力,勉强给回复下吧
回复 支持 反对

使用道具 举报

冯安娜 发表于 2016-10-18 02:22:58
替楼主问候看帖不回帖的!
回复 支持 反对

使用道具 举报

刘良华 发表于 2016-10-23 01:50:59
路过 帮顶 嘿嘿
回复 支持 反对

使用道具 举报

983828887 发表于 2016-11-5 16:26:47
开往春天的坦克!
回复 支持 反对

使用道具 举报

谷雪 发表于 2016-11-6 12:09:51
一直在看
回复 支持 反对

使用道具 举报

*滑动验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

我要投稿

推荐阅读

扫码访问 @iTTTTT瑞翔 的微博
回页顶回复上一篇下一篇回列表手机版
手机版/CoLaBug.com ( 粤ICP备05003221号 | 文网文[2010]257号 )|网站地图 酷辣虫

© 2001-2016 Comsenz Inc. Design: Dean. DiscuzFans.

返回顶部 返回列表