首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > 移动开发 >

Tell, don't ask 准则

2013-03-01 
Tell, dont ask 原则Tell, dont ask 原则 ? ?Source: ?http://www.aqee.net/tell-dont-ask/?前些时间我

Tell, don't ask 原则
Tell, don't ask 原则 ? ?Source: ?http://www.aqee.net/tell-dont-ask/?

前些时间我曾经翻译过一篇叫做《这里我说了算!》的文章,里面作者讲述了关于“命令,不要去询问(Tell, Don’t Ask)”原则:

我看到的最多被违反的原则是“命令,不要去询问(Tell, Don’t Ask)”原则。这个原则讲的是,一个对象应该命令其它对象该做什么,而不是去查询其它对象的状态来决定做什么(查询其它对象的状态来决定做什么也被称作‘功能嫉妒(Feature Envy)’)。

这篇文章里有个很生动的例子,我至今记忆犹新:

if (person.getAddress().getCountry() == “Australia”) {

这违反了得墨忒耳定律,因为这个调用者跟Person过于亲密。它知道Person里有一个Address,而Address里还有一个country。它实际上应该写成这样:

if (person.livesIn(“Australia”)) {

非常的明了。今天我又看到一个关于“Tell, Don’t Ask”原则的文章,里面提供了4个关于这个原则的例子,都很有价值。

例一

不好:

<% if current_user.admin? %>  <%= current_user.admin_welcome_message %><% else %>  <%= current_user.user_welcome_message %><% end %>

好:

<%= current_user.welcome_message %>

例二

不好:

def check_for_overheating(system_monitor)  if system_monitor.temperature > 100    system_monitor.sound_alarms  endend

好:

system_monitor.check_for_overheatingclass SystemMonitor  def check_for_overheating    if temperature > 100      sound_alarms    end  endend

例三

不好:

class Post  def send_to_feed    if user.is_a?(TwitterUser)      user.send_to_feed(contents)    end  endend

好:

class Post  def send_to_feed    user.send_to_feed(contents)  endendclass TwitterUser  def send_to_feed(contents)    twitter_client.post_to_feed(contents)  endendclass EmailUser  def send_to_feed(contents)    # no-op.  endend

例四

不好:

def street_name(user)  if user.address    user.address.street_name  else    'No street name on file'  endend

好:

def street_name(user)  user.address.street_nameendclass User  def address    @address || NullAddress.new  endendclass NullAddress  def street_name    'No street name on file'  endend

好的面向对象编程是告诉对象你要做什么,而不是询问对象的状态后根据状态做行动。数据和依赖这些数据的操作都应该属于同一个对象。

命令,不要去询问!

?

热点排行