设计模式作为(缺失的)语言特性

7
有时人们将设计模式称为缺失的编程语言特性。为避免关于什么是设计模式的辩论,让我们只考虑原始的GoF模式。例如,在Scala中支持使用关键字object的单例模式消失了。
关于此问题,有一些资源可供参考,特别是来自C2 wiki的Are Design Patterns Missing Language Features或来自SO的Are design patterns really language weaknesses?。但是我找不到一个非意见主张、客观和全面的解决方案。
理想情况下,我希望有一个矩阵,其中包含GoF设计模式(行)和一些主流编程语言(列),每个单元格都会涉及特定编程语言中该模式的讨论。
为避免关于要考虑哪种PL的辩论,我们还可以选择Java(作为静态类型的OO代表)、Smalltalk(作为动态类型的代表)、Haskell(作为函数式代表)、Scala(作为混合oo/函数式代表)、Lisp(作为元编程代表)、JavaScript(作为基于原型的代表)。其他PL可以作为附注或评论留下。我知道我们可以就这个选择进行争论,但对于这些语言来说,已经足够有趣了。
无论如何,这始终是一个开放性问题,但我认为提出这样的问题已经足够专注,以获得最佳答案。
也许这个矩阵已经存在于某处?或者有人具备足够的知识来制作它?或者有人足够热心,开始并将其变成维基答案,以便其他人可以继续?

为什么不写一篇博客文章,并随着您发现模式的新实现而不断完善它,而不是在SO上提出一个开放性的主观问题呢? - slugster
这个问题可能没有一个最好的答案。我会建议使用社区维基。 - Don Roby
@slugster 我的想法确实是要写这样一篇博客文章(或者是我的一个朋友会写),问题在于如何收集关于特定模式在某种语言中的最佳讨论参考。然后我可以将其编译成一篇博客文章。同时,我可能也会回答自己的问题并草拟矩阵的草稿。 - ewernli
@Don Roby 嗯,一个带有链接的矩阵有点模糊的客观存在,但我们可以就链接的质量等方面进行争论。所以我对此有些复杂的感受,也许社区维基更好一些。 - ewernli
2个回答

5

设计模式中的模式是人们在不同编程语言中使用的模式集合的一个子集。作者非常清楚,这些模式仅适用于面向对象编程语言,因此其中许多模式在该上下文之外将毫无意义。

同时,在其他语言中存在着很多在面向对象编程语言中不需要的模式。考虑到在C或Scheme中实现对象本身就是一种模式,在汇编中,调用堆栈就是一种模式。


+1,我已经编写了面向对象的C代码(以及状态机C代码,这两者非常相似)。我认为,在任何具有超过100K代码空间的设备上,使用汇编编写调用堆栈更多是一种求助而不是一种模式。 - detly
有些模式在其他情境下不适用。如果有些模式完全不相关,跳过它们也没关系,或者提到某个模式在另一种语言/范例中根本没有意义也可以。但我觉得以下模式值得在面向对象之外的情境下讨论:适配器、装饰器、代理、命令、解释器、观察者、状态、策略、访问者。是的,有很多模式和语言,所以我必须在某种程度上限制问题的范围。 - ewernli

1

个人经验是,经过几年的面向对象编程(OOP)后,我发现设计模式的问题在于它们突显了OOP的问题,以及在与所建模领域相关的数据中难以看到模式。有时候很难看到树木因为太多树林了。 OOP中的一些工件只是为了解决在这种特定范例或获取封装状态和访问时存在的问题。

我认为设计模式很棒,我也使用它们,但是它们被视为解决OOP无法客观地处理数据结构和函数的问题的方法,以便可以应用经过验证的公式。一个简单的例子是Singleton Object。在使用函数语言时,它就消失了,不再是问题。

当我询问UML是否可用于建模函数语言时,Stack Overflow上的一位先生说,函数编程语言的建模语言是数学。我认为这是理解为什么模式与函数编程语言无关的关键,因为它们背后的理论深植于数学结构。

我不能帮你列一个抄袭笔记,但是我可以十分确定的是,GOF模式不适用于函数式编程语言,因为它们直接涉及数学中真正的模式,而函数式语言的美妙之处在于它们可以(在大多数情况下)直接映射到解决数学问题多年的方法。也许可以说,函数式语言的设计模式是具有一对一关系的数学定理,而面向对象则具有一种人为抽象的形式,有时会妨碍编程。

我认为有些设计原则适用于所有语言,如MVC,多层架构,横向和纵向扩展等。但这些原则我将视作良好的软件设计实践,而非设计模式。


你实际上说的是,有些模式在使用其他语言时会消失,这正是我想要调查的。也许我应该先提取GoF模式解决的问题,然后看看如何在其他语言中解决这个问题。例如,在面向对象编程中,单例解决了对象或数据结构唯一性的问题,并在严格的函数式语言中消失了。或者Haskell类型类和组合模式之间是否存在某种概念上的关系?当然,我有点在比较苹果和橙子,但这就是有趣的地方。 - ewernli
或者说,在面向对象的AST解释中,你需要使用Visitor,而在函数式编程中,由于重载(参见表达式问题),你不需要这样做。或者,如果编程语言支持元编程,则解释器模式会消失。或者,如果您有类似Scala隐式和提取器等功能,则可以使用适配器。 - ewernli
是的,我也对比较感兴趣。 GOF模式确实与面向对象设计有关,我认为它们代表的并不是什么新东西,但它们确实使得每个人都能够获得这些模式/算法。在无知中,我只是把它们当作指南,但最近深入研究函数式风格后,我开始意识到其中有更多的深度。访问者模式是一个典型的OO示例,基本上是将一种形式转换为另一种形式的函数。 - WeNeedAnswers
1
我对Lisp程序员对模式的看法非常感兴趣。AST是该语言的核心,没有花哨的修辞和太多糖衣包装。我认为我们在日常编程中都会使用模式,其中许多模式甚至不知道我们正在使用它们。我多年来一直在使用IOC/Injector模式,后来读了Fowler的书,想到“你知道什么!” :) - WeNeedAnswers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接