反for-if编程模式

这些年来,我看到过大量的反编程模式。我感觉应该向大家分享一些。

今天,我要介绍的是被我称作反for-if编程模式的反模式,也就是人们所说的”我们卖给你整个座位,但你需要的只是一个边。”
这是一个特殊的反for-case模式,其中所有的情况中只有一次会是null。

for (int i = 0; i < 100; i++) {
  if (i == 42) { do_something(i); }
}

这种情况可以简单的写成

do_something(42);

这个反for-if模式可以表现成各种各样的形式。比如:

foreach (string filename in Directory.GetFiles("."))
{
    if (filename.Equals("desktop.ini", StringComparison.OrdinalIgnoreCase))
    {
        return new StreamReader(filename);
    }
}

它是在一个目录里遍历查找一个指定文件,如果找到了,就返回文件的数据流。这段代码的一种不是那么折腾的写法是

if (File.Exists("desktop.ini"))
{
    return new StreamReader("desktop.ini");
}

请注意,两个版本的代码片段具有相同的竞争条件:如果这个desktop.ini本来是存在的,但在你创建Stream­Reader之前被删掉了,你就会得到一个File­Not­Found­Exception错误。

再举一个例子:

foreach (object o in hashtable.Keys)
{
    if (o == "target") return hashtable["target"];
}

等同于

return hashtable["target"];

我猜测这些家伙不喜欢在图书馆里通过书名找一本书,因为他们的做法是如此的繁琐:
他们来到图书馆里员面前说,“把你所有的书都给我,”然后他们拿着装满了上千本书的篮子,坐到墙角里自言自语:
“不是,这本书的书名不对”,

“不是,这本也不是”,

“标题还是不对。”

“这本书呢?”

”不是,也不是这本。“

”老天,我要这样一本一本翻到什么时候…“

[英文原文:Introducing the for-if anti-pattern ]
分享这篇文章:

12 Responses to 反for-if编程模式

  1. Eric says:

    感觉应该翻译成”XX反模式”而不是”反XX模式”

    • gaobaba says:

      同意。

      标题给人的感觉是,咦,这个 for-if 模式是什么。但这里并不存在一个 for-if 模式给人去反。

      这里的反模式(anti-pattern) 是常见错误的意思。

  2. jsz says:

    一般情况下的判断条件不是完全的相等吧,比如 if (o > “target”) 的情况应该比 if (o == “target”) 更常见。

  3. xwsoul says:

    弱弱的问下 File.Exists 这个方法又是如何实现的呢?

  4. 依云 says:

    @shindo: 这样只能说明文件系统太笨了。我知道有些文件系统的目录项是使用查找树实现的,所以即使有大量文件查找起来也不慢。

  5. gaobaba says:

    这真的是个常见的问题。不过,因为举的两个例子都比较夸张,程序员或许或认为,我才不会这么写代码。

    常见的情形是,一个功能需要完成两个动作,一个是查找对象,查找的结果可能是一个,也可能是一组,然后在针对查找的对象做一些操作。

    这个时候,要考虑单一职能原则,将查找和针对查找结果的操作分开。但我看到太多的代码,是将它们混在一起的。这就是这个 for-if anti-pattern 的隐晦形式。

    在实际的代码中,会有若干种不同的查找需求,针对结果的操作也会有一些不同的变化。混在一起的结果,因为组合方式不同,不少代码功能类似,却很难提取成公用模块,造成大量的重复代码。

    按这个思路去思考,就很容易看出文中的两个例子该如何修改了。

  6. SunshineLink says:

    for (int i = 0; i < 100; i++) {
    if (i == 42) { do_something(i); }
    }

    这种情况可以简单的写成

    do_something(42);

    这篇文章完全是哗众取宠,谁能写出第一种情况的代码?谁见过?

  7. 西瓜肚圆圆 says:

    我觉得作者写的并不是完全没有,随便找找老代码,或者给别人review代码的时候可能就会发现这样的情况

  8. 老贺  这篇文章

发表评论

邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据