如何正确地使用设计模式?

有感于@winter 的这个回答“设计模式的荼毒”体现在何处? 故提问。一直也很困惑如何避免过度设计?
关注者
3,814
被浏览
568,865
登录后你可以
不限量看优质回答私信答主深度交流精彩内容一键收藏

除非你还在写 Java,否则设计模式真没多大用处。

---- 补充几句 ----

首先明确一点,这里说的“设计模式”,是“面向对象设计模式”的简称,以 GoF 书中列出的 23 个模式为代表。

不要把什么都归为模式,比如 “if-then-else 模式”、“for each 模式”就不是(面向对象设计)模式。Like, the inverse, reverse, double-back-flip pattern—whatever. Oh, you mean a loop? OK. --- Jamie Zawinski

类似的,thread pool、thread-per-connection、process-per-connection、thread local storage、scoped locking、readers-writer lock 等等也不是面向对象设计模式。

赞同

@winter

说的 “建议不要泛泛地讨论和学习‘设计模式’,而是具体到每一个模式。”

如果你用的语言能把类型像变量一样赋值并传来传去,很多创建型模式就没用了。

如果你用的语言能把函数像变量一样赋值并传来传去,很多行为模式就没用了。

如果你用的语言 style 反对叠床架屋的 class hierarchy,很多结构模式就没用了。

几个简单具体的代码示例:

1. C# 内置了 delegate/event,Observer 模式就没用了。

2. 如果你的语言的 typeof 操作符能得到 runtime type,那么 Prototype 模式就没用了。比如

class Base(object):
  pass

class Derived(Base):
  pass

def clone(x):
  return type(x)()

if __name__ == '__main__':
  d = Derived()
  print type(d)  # <class '__main__.Derived'>
  c = clone(d)
  print type(c)  # <class '__main__.Derived'>
  b = Base()
  print type(b)  # <class '__main__.Base'>
  a = clone(b)
  print type(a)  # <class '__main__.Base'>

3. 如果类型能像变量一样赋值和传递,Factory method 模式就没用了。比如

class Base(object):
  pass

class Derived(Base):
  pass

def getCreator(ty):
  def create():
    obj = ty()
    # initialize obj
    return obj
  return create

if __name__ == '__main__':
  d = getCreator(Derived)
  b = getCreator(Base)

  print type(d())  # <class '__main__.Derived'>
  print type(b())  # <class '__main__.Base'>
# 这个例子做作了一些,可以看第二个链接里的例子。

更多的例子见

norvig.com/design-pattecdn.oreillystatic.com/e

4. 如果函数能像变量一样赋值和传递,Command、Strategy 等模式就没用了。

5. EventHandler/ConcreteEventHandler 这种 callback API 风格在现代语言里基本绝迹,C++ 有 std::function、C# 有 delegate、连 Java 8 都有了 Lambda,更别说动态语言了。

6. 有的语言有全局变量,Singleton 模式就没用了。Singleton 是最简单也最被滥用的模式。

7. 有的语言有 multiple dispatch,Vistor 模式就没用了。其实 Vistor 模式一直就没啥用。