设计模式真的是语言弱点吗?

时间:2009-10-16 16:53:49

标签: design-patterns history language-design

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

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

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

12 个答案:

答案 0 :(得分:46)

一些标准化的设计模式 - 适配器,工厂,命令,访问者等 - 是与其他语言融合的功能的近似值。在我的头顶:

  • C#中的事件处理程序是观察者模式的烘焙版本。想一想如果你每次都要自己动手观察,你如何用C#连接事件。

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

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

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

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

  • 装饰器模式允许您在运行时附加或删除对象的行为。在JavaScript中,由于“原型”OO模型,您可以添加或删除函数而无需显式实现装饰器模式。

因此,我们有一堆模拟其他语言固有特征的设计模式。功能嫉妒并不一定表示语言的弱点 - 它是你需要编写一遍又一遍的样板代码,这表明语言的弱点。

答案 1 :(得分:18)

我不会称它们为缺陷。

高阶语言处理的概念高于低阶语言。从构造角度考虑它。

您可以在炼油厂层面建造一座建筑物,铣削木材,冶炼钢材,并将建筑物整合在一起。

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

您可以购买预制的墙壁和桁架,然后将它们建造成一座建筑物。

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

建造一座大楼和大梁是否缺少预制墙特征,或以某种方式出现缺陷?

答案 2 :(得分:10)

你在软件设计中做过三次或更多次的事情就形成了一种模式。

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

有些人会用很酷的名字来封印。这些成为设计模式。有意识的重复。

有些只是“最佳做法”或“这对我有用”。这些是没有清晰度的设计模式。

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

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

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

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

答案 3 :(得分:2)

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

答案 4 :(得分:2)

我认为Ewan提出了一个引人入胜的观点。以他的“子程序”为例。在早期的编程语言中,将参数传递给子例程并返回结果的想法是您必须显式编码的。在现代语言中,它是内置的。或者采取另一个例子:如果/ then / else被构建到大多数(如果不是全部)现代语言中。但是在我的汇编时代,我不得不编写代码来实现这一目标。当然不是很多,但是,你必须实际编写jump或goto语句来绕过else块。事实上,你必须自己编写这些东西,这意味着不同的程序员会以稍微不同的方式做到这一点,并且有一种无限的诱惑,要聪明,并且在这个程序中做一点点不同,以使其更有效率或获得其他一些所谓的优势。

最新的例子是迭代器。你必须用C ++和早期版本的Java手工编写它们,但它们是内置于Java 5.这可以说是语法糖,你也可以简单地创建迭代器函数。我个人认为这是一个很好的功能。它从根本上提高了我的生产力吗?否。

我们一直在做什么,应该在逻辑上构建到语言中以标准化和简化它?一个引人入胜的问题。我不认为任何人都会认真地声称,即使他们最喜欢的语言是完美的,也绝对没有任何改进。但是下一种语言的方向是什么呢?

当然,一些已添加到语言中的功能是无用的额外行李。在我看来,Java enum的做法超出了必要的范围,他们无缘无故地添加了许多行李。我相信其他人会不同意并说他们发现它们非常有用。

我没有结论。我只是同意这是一个引人入胜的问题。

答案 5 :(得分:2)

我读过某些地方,比如“你的模式越多,你的语言就越不强大”,我发现这个定义非常好。

原因是IMO清楚:如果你看到一个重复的模式(或者你必须使用它),这意味着它是一种在逻辑层面上的复制粘贴。当然它没有copy'n粘贴语句那么糟糕,但它仍然是冗余。我一次又一次地重复着自己。

语言表达越多,您应该越多地捕获并通过在重用而不是重新实现中转换它来解决这个冗余,并且在源代码中重用将更容易阅读和理解。

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

当然有时你可以尝试捕捉某些东西的本质,但重用可能比重新实现更难以阅读(我正在考虑例如{{1}中C ++的某些部分“高级”内容。 })。这是IMO一个明确的信号,表明该语言不够表达。

答案 6 :(得分:1)

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

答案 7 :(得分:1)

我想知道在它变得太大之前你能用多少语言填充它。

我喜欢与我合作的语言,足够小,可以立刻掌握我的想法。 DI等模式与结构问题有关;这应该是语言的一部分吗?

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

对于代码约定(需要,确保),当它是语言的第一类部分时很好,但它不是必需的。它仍然可以成为图书馆的一部分。

答案 8 :(得分:0)

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

答案 9 :(得分:0)

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

一种可以无限制地执行此操作的语言将是没有严格语法的语言。 (或以另一种方式,允许无缝地同化任何高级模式的那个)。 见metalinguistic abstraction

我想到的是scheme / lisp。

答案 10 :(得分:0)

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

由于很多事情都在不断发展,我认为Enterprise Integration Patterns会很受欢迎。

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

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

答案 11 :(得分:0)

要回答“他们将有哪些模式?”这个问题:

Java 有 Singleton pattern,它是在 Kotlin 中实现的,带有 object keyword

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