【问题标题】:Are design patterns really language weaknesses?设计模式真的是语言弱点吗?
【发布时间】:2010-12-07 10:35:34
【问题描述】:

今天的模式应该be seen as defects or missing features in Java and C++吗?

  • 子程序是50、60年代机器语言的一种设计模式。
  • 面向对象的类是 70 年代 C 的一种设计模式。
  • 访问者、抽象工厂、装饰器和外观是当今 Java 和 C++ 的设计模式。

    明天的语言会是什么样子? 他们会有什么模式?

【问题讨论】:

    标签: design-patterns history language-design


    【解决方案1】:

    回答“他们会有什么模式?”的问题:

    Java 有 Singleton pattern,它在 Kotlin 中使用 object keyword 实现

    我不知道模式是否是语言的弱点,但对我来说,Kotlin 的优势之一是它使单例的使用变得容易。

    【讨论】:

      【解决方案2】:

      设计模式不是语言的弱点。他们为反复出现的问题提供设计解决方案。

      由于许多事情随着时间的推移而不断发展,我认为Enterprise Integration Patterns 会很受欢迎。

      如果不同的企业应用程序必须进行通信,这些模式提供了最佳解决方案。

      1. Integration Styles 记录集成应用程序的不同方式,提供集成技术的历史记录。所有后续模式都遵循消息传递样式。
      2. Channel Patterns 描述如何通过消息通道传输消息。大多数商业和开源消息传递系统都实现了这些模式。
      3. Message Construction Patterns 描述通过消息传递系统传播的消息的意图、形式和内容。本节的基本模式是消息模式。
      4. Routing Patterns 讨论如何将消息从发送者路由到正确的接收者。消息路由模式使用来自一个通道的消息并根据一组条件将消息重新发布到另一个通道,通常无需修改。本节介绍的模式是消息路由器模式的特化。
      5. Transformation Patterns 更改消息的内容,例如以适应发送和接收系统使用的不同数据格式。可能需要添加、删除数据或重新排列现有数据。本节的基本模式是消息转换器。
      6. Endpoint Patterns 描述消息系统客户端如何生成或使用消息。
      7. System Management Patterns 描述了保持基于消息的复杂系统运行的工具,包括处理错误情况、性能瓶颈和参与系统的变化。

      【讨论】:

        【解决方案3】:

        我在某处读过类似“你拥有的模式越多,你的语言就越不强大”之类的东西,我觉得这个定义非常好。

        原因很清楚 IMO:如果您看到重复的模式(或者您必须使用它),则意味着它是一种逻辑级别的复制粘贴。当然它没有复制粘贴语句那么糟糕,但它仍然是冗余的。我还在一遍又一遍地重复自己。

        语言的表现力越强,您就越应该能够通过将其转换为重用而不是重新实现来捕获和分解这种冗余,并且重用将在源代码中更易于阅读和理解。

        每次你发现自己再次做同样的事情时(包括例如“好的......让我们在这里实现一个抽象工厂”),这意味着这应该在更高的层次上表达出来。

        当然,有时您可以尝试捕捉事物的本质,但重用可能比重新实现更难读(例如,我在想 <algorithm> 中的 C++“高级”内容的某些部分) .这是 IMO 语言表达力不足的一个明显迹象。

        【讨论】:

          【解决方案4】:

          每种语言都是一组任意的设计模式,其语法作为所选模式的符号。对于未选择的模式,您必须干预语法的约束来表达它们。 大多数语言不允许其语法发生太大变化以吸收更高级别的模式。

          一种可以无限制地做到这一点的语言将是一种没有严格语法的语言。 (或者以另一种方式,允许无缝吸收任何高级模式)。 见metalinguistic abstraction

          我想到的是scheme/lisp。

          【讨论】:

            【解决方案5】:

            一些规范化的设计模式——适配器、工厂、命令、访问者等——是其他语言中特性的近似值。在我脑海中浮现:

            • C# 中的事件处理程序是观察者模式的内置版本。想想如果您每次都必须滚动自己的观察者,您将如何在 C# 中连接事件。

            • 访问者模式是multimethodsmessage forwarding 的详细近似或pattern matching 的非常弱的形式。

            • 命令模式封装了特定的行为,因此您可以在方法之间传递对象,这或多或少接近于一流的函数。

            • 策略模式允许您将一种行为动态地插入到对象中,这样您就可以随时通过将一种行为与另一种行为交换来修改对象。在函数式编程世界中,我们称之为函数组合。

            • 抽象工厂模式接受一个参数并返回一个工厂作为结果。通常,您可以将工厂视为基本上是函数的包装器(更具体地说,是构造器的包装器)。因此,您将参数传递给函数并得到一个函数作为结果,使这种模式非常类似于柯里化。

            • 装饰器模式允许您在运行时将行为附加或删除到对象。在 JavaScript 中,借助“原型”OO 模型,您无需显式实现装饰器模式即可添加或删除函数。

            所以,我们有一堆设计模式可以模拟其他语言的固有特性。功能嫉妒不一定表明语言的弱点——它是您需要一遍又一遍地编写的样板代码,它表明了语言的弱点。

            【讨论】:

            • 我真的很喜欢这个答案。它表明一些命名模式已经在日常使用中。这让我想,“好吧,这是你为明天的超级语言设计的一组特殊模式”。
            • “明天的超级语言”不能来自今天的语言。它必须完全不同——否则我们只会使用带有一些扩展的当今语言。
            • @S.Lott:“明天的超级语言”可能会在技术奇点的转折点出现,并且,正如我可以肯定的那样,所有的设计模式都会过时;)
            • 我也很喜欢。最后一句话可能是这个问题的最佳答案。我也从未想过 factory-factory 是一种非常冗长的柯里化形式。
            • @Juliet:没有什么能让设计模式过时。任何时候你重复某件事,这就是一种设计模式。它总是发生在所有学科中,总是。
            【解决方案6】:

            你在软件设计中做三遍或三遍以上的每一件事都会形成一个模式。

            每次重复。每一次重复。每次重复。

            有些人得到了很酷的名字。这些成为设计模式。有意识的重复。

            有些只是“最佳做法”或“这对我有用”。这些是不明确的设计模式。

            有些只是“你通常会做的事情”。这些是设计模式,没有任何有意识地意识到你在重复自己。

            设计模式与语言的弱点或不完整性无关。他们有一切与好的想法有关,有意识地重复使用。

            今天的设计模式并不是通向明天语言的王道。语言范式并没有通过一系列“对以前语言的错误修复”来推进。如果是这样,我们就永远不会创建 Visual Basic。

            与简单的编程语言功能集相比,设计模式是一种更大、更广泛的智力工具。

            【讨论】:

            • 好的,但是你回答他的问题了吗?
            • 我以为我做到了,但我编辑了我的答案以更加强调我的观点。
            • 我认为这是一个很好的观点。看起来这更像是许多更知名的 - 主要是 GoF - 模式在其他语言中是多余的。
            【解决方案7】:

            我认为 Ewan 提出了一个有趣的观点。以他的“子程序”为例。在早期的编程语言中,将参数传递给子例程并返回结果的想法是您必须明确编码的东西。在现代语言中,它是内置的。或者再举一个例子:If/then/else 内置在大多数(如果不是所有)现代语言中。但回到我的汇编时代,我必须编写代码来完成它。当然不是很多,但是,您实际上必须编写 jump 或 goto 语句才能绕过 else 块。事实上,你必须自己编写这些东西,这意味着不同的程序员会以稍微不同的方式来做这件事,并且有无穷无尽的诱惑要聪明,在这个程序中做一些不同的事情,以提高效率或获得其他一些好处假定的优势。

            最近想到的例子是迭代器。您必须用 C++ 和 Java 的早期版本手动编写它们,但它们是内置于 Java 5 中的。这可以说是语法糖,您只需创建迭代器函数就可以了。个人认为这是一个不错的功能。它是否从根本上提高了我的工作效率?没有。

            我们一直在做的事情是否应该在逻辑上内置到语言中以标准化和简化它?一个有趣的问题。我不认为有人会认真声称即使他们最喜欢的语言也是完美的,而且绝对不可能有任何改进。但是下一个语言的方向会是什么?

            当然,添加到语言中的某些功能是无用的额外包袱。在我看来,Java enum 做的比必要的多,他们无缘无故地增加了一堆包袱。我相信其他人会不同意并说他们发现它们非常有用。

            我没有结论。我只是同意这是一个有趣的问题。

            【讨论】:

            • 我必须将原始想法归功于链接的文章。你关于语法糖的观点让我想到了不同类型的语言改进之间的区别。一方面是那些只会使创建我们已经能够组合在一起的结构变得更容易的结构,尽管使用函数和类很费力。另一方面,真正出色的创新,在子程序或 if-else 块的规模上,标志着编程领域的根本转变。
            • 我有点不同意,因为我很难想到通过足够的努力无法实现的编程结构。您可以编写子程序或 if/else 或在汇编程序中进行面向对象的编程,这很难。因此,这不是困难但可能与不可能,但它可能是困难但实用与工作量太大。但我不认为这是你的重点,而是你在谈论“可爱”和“聪明”之间的区别。对吗?
            【解决方案8】:

            不,它们没有缺少语言的功能或缺陷。但是语言应该提供一种方法来编写有用的模式的代码更容易而不是困难。这就是语言所提供的功能可能是福音也可能是障碍的地方。

            【讨论】:

              【解决方案9】:

              确实存在有助于在语言中使用某些模式的框架,因此它们更多是一种选择,而不是必须的。对于某个项目,有些模式可能是您不需要的,因此将其中的许多模式作为主要语言功能只会施加限制,而不是促进生产性工作。

              【讨论】:

                【解决方案10】:

                我想知道在语言变得“过大”之前,你能塞进多少东西。

                我喜欢我正在使用的语言,它小到足以让我一下子记住。 DI 等模式与结构问题有关;这应该是语言的一部分吗?

                开发人员真正需要掌握多少语言?

                在代码契约(需要,确保)的情况下,这是语言的一流部分,但它不是必需的。它仍然可以是库的一部分。

                【讨论】:

                • 可以提出一个论点,即语言应该尽可能小且正交,并且它的库应该很大。换句话说,尽可能多地卸载到库中,而不是用许多很少使用的深奥语法和特殊情况来混乱语言。
                • 是更难记住更大的语言,还是更小的语言加上额外的模式?
                • 在语言中更容易拥有那些具有“通用应用”的核心内容,而在库中拥有特定情况下需要的那些东西。您可以随时在参考资料中查找模式,但您在语言中需要的日常内容应该牢记在心。
                • 因此,通常您可以使用较小(但完整)的语言提高工作效率。
                【解决方案11】:

                我不会称它们为缺陷。

                高阶语言比低阶语言处理更高层次的概念。在建筑方面考虑它。

                您可以在炼油厂级别建造建筑物,铣削木材,冶炼钢铁,然后以这种方式组装建筑物。

                您可以购买木板和钢梁,然后将它们建造成建筑物。

                您可以购买预制墙和桁架并将它们建造成建筑物。

                您可以购买一栋建筑,然后从内部开始。

                用木板和大梁建造的建筑物是否缺少预制墙的特征,或者在某些方面存在缺陷?

                【讨论】:

                • 通常在谈论模式时,您只是使用相同的设计,但您每次都必须自己编写整个代码。与预制材料的类比不适用于 IMO ......那将使用一个库(当然也没有什么不好的)。
                • 我的观点更多的是关于何时将模式融入语言。例如,当您不必自己从头开始编写观察者模式时,这有点像在构造中使用预制组件。虽然这不是一个完美的比喻,但我同意你的看法。
                【解决方案12】:

                我认为一些设计模式确实代表了语言的弱点,而新语言将现有模式融入一等公民。 Google 的NOOP 是一个新语言的示例,它采用其他语言中的现有设计模式(依赖注入、不变性等)并将它们合并为一流的语言级功能。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2015-07-04
                  • 2011-04-22
                  • 2010-09-12
                  • 2018-08-05
                  • 2011-02-01
                  • 2011-03-23
                  • 1970-01-01
                  相关资源
                  最近更新 更多