代码之丑(十四)–多个构造函数

代码评审,我对一个TreeSet产生了兴趣。

TreeSet<String> configuration = new TreeSet(); ... Handler handler = new Handler(configuration);

“为什么要用TreeSet呢?”,我问道。

“因为这是构造函数的参数决定的。”,有人回答。

“可以打开源码看一下吗?”,对于这种处理,通常人们都会选择HashSet,好奇心驱使我要进一步专研一下这段代码。

我看到了这个构造函数的声明:

public Handler(TreeSet<String> configuration) {
  ...
}

在我开始研究这个构造函数使用TreeSet的缘由之前,我看到了另外一个构造函数,或许它更能满足我的心理需求:

public Handler(HashSet<String> configuration) {
  ...
}

“为什么会有一个用到HashSet构造函数?它和用到TreeSet的有什么不同”,我继续追问。

“它们是分别处理两种情况的,在不同的配置下起作用。”

我终于知道为什么会有TreeSet,因为HashSet已经被人用了,为了支持另外一种情形,TreeSet被人从墙角了挖了出来。可是如果不深究代码,谁又能知道这其中的奥妙呢?显然,我们需要一个更具表达力的写法。

之所以陷入这样的坑,根源在于构造函数,因为构造函数只能有一个名字。其实,这里只是要解决构造的问题,而面对这个问题,解决方式几乎再直白不过了:工厂方法。

class HandlerFactory {
  public static Handler createTrivialHandler(Set<String> configuration) {
    ...
  }

  public static Handler createFancyHandler(Set<String> configuration) {
    ...
  }
}

这里,用两个名字上有更明确意义的函数替代之前的那两个需要强大理解力的构造函数。当然,这里的参数用了Set,连具体的类型都省了,真正的面向接口编程。

事实上,如果一个类有多于一个的构造函数,都是值得考虑的。我曾写过一篇《构造函数沉思录》专门讨论这个问题。

作者简介

郑晔,ThoughtWorks公司首席咨询师,拥有十多年企业级软件开发经验,热衷于探索各种程序设计语言在真实软件开发中所能发挥的威力,致力 于探寻合理的软件开发方式,加入ThoughtWorks公司后,投入到敏捷开发方法的实践之中,为其他公司提供敏捷开发方法方面的咨询服务。他的 blog是梦想风暴,其微博是@dreamhead

查看原文:代码之丑(十四)


感谢张凯峰对本文的审校。

给InfoQ中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ)或者腾讯微博(@InfoQ)关注我们,并与我们的编辑和其他读者朋友交流。

This entry was posted in Best Practices. Bookmark the permalink.

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s