为什么不将设计模式添加到语言构造中?


11

最近,我正在与一位同事交谈,他提到他的公司正在努力将MVC设计模式添加为PHP扩展。

他解释说,他们编写了C代码以添加Controllers, Models and Views到语言构造中以提高性能。

现在,我知道MVC是一种架构设计模式,已在Web应用程序中广泛使用,但是我仍然不得不遇到例如具有Controllers语言构造的语言。

恕我直言,将设计模式集成到语言中可以强调良好的OO设计的重要性。

那么,为什么不将最常用的设计模式(MVC,工厂,策略等)添加到语言构造中呢?

如果问题听起来太宽泛,则可以将问题限制为仅PHP。

编辑:

我并不是在暗示开发项目时必须使用设计模式。实际上,我提倡只要可行就保持简单的方法。


19
有一种流派说,有许多模式是一种语言气味。可以肯定的是,GO4书中的许多图案在Lisp中消失了或变成了1衬。
Zachary K

5
“在任何项目中,建筑工厂都是100%保证的。” 然后,您从事不良项目。尽管工厂是有用的模式,但远不能保证。任何OOP都有工厂模式。它称为构造函数。
欣快的2012年

9
总的来说,我对整个OO表示怀疑。是的,可能会有促进可重用性的想法,但这根本行不通。而且,一旦有了一些真正强大的工具,例如元编程,高阶函数,强大的类型系统,模块等,您就可以轻松地将所有OO设计模式表达为新语言的构造,但是您将不想这样做,因为有了这些,您将不再需要任何OO。
SK-logic

2
因为这意味着添加通用语言中的功能,所以您不希望具有2000个功能的语言,因为这些功能之间的所有语法和微妙的交互作用都不适合您。取而代之的是,您需要一种语言,它具有最少的功能集,可以足够简洁地容纳许多设计模式。如果可以使用不太差劲的语法根据现有语言功能来编写设计模式,那么添加新功能的成本就会高得多,并且不必要地使语言复杂化。
Lie Ryan

5
还有一种思想流派(我所属)说,设计模式只是针对语言缺陷的解决方法。在他们看来,所有现有的设计模式都不会以完美的语言存在。但是考虑到最受欢迎的语言远非完美,因此我们只能采用这些解决方法。 (示例)
BlueRaja-Danny Pflughoeft

Answers:


20

设计模式一直添加到语言构造中。听说过子程序调用设计模式吗?没有?我也不。这是因为子例程调用(在1950年代初期一种设计模式)几乎立即被添加到了语言中。如今,它们甚至出现在CPU的机器代码指令集中。

For循环设计模式呢?该While循环设计模式?该交换机设计模式?该对象设计模式?该设计模式?所有这些都已添加到某些语言中。


实际上,子程序调用的各种设计模式在50年代末60年代初很普遍(至少在汇编程序和机器代码中),并且还出现在M6800(8位)中。搜索Wheeler jumpModified Wheeler jump
Vatine 2012年

TI-83 Plus当我在2001
。– Izkata 2012年

12

他们之中有一些是。例如,迭代器是许多语言及其标准库中的语言功能(在那里,foreach和yield return)。观察者也经常以事件的形式出现(不是PHP中的-您必须自己管理回调订阅)。命令是WPF中的核心功能。

其他许多语言并不会真正从语言支持中受益(并且会使语言变得更加笨拙)-如果可以为控制器设计语言功能,将如何简化Controllers?作为类,它们受益于已经存在的支持类的所有基础结构-您可以实例化它们,将它们传递给其他对象,例如对它们进行单元测试。

IMO可以从某种语言支持中受益的MVC唯一组件是View(带有一些正式的模板引擎)-并且已经在PHP中得到了支持-您能够动态创建和加载PHP脚本(通常与用作模板的某种预处理)。

工厂方法也是如此-如果您可以使用所需的任何语言功能,该如何简化呢?某些语言(例如C ++)缺少的一项功能是能够从该类型名称构造对象,但是大多数高级语言都可以做到这一点(甚至不必创建有用的工厂方法)。除此之外,您所需要做的就是能够创建一个实例化并返回和对象的方法。


10
甚至面向对象的方向也可以被认为是一种有用的特定模式,因此被烘焙成多种语言。通常,模式的存在指示缺少语言功能。
安德里亚(Andrea)2012年

7

确实确实将一些设计模式添加为语言构造-只是因为人们一旦将其内置就开始将它们视为“语法”,所以它们没有被这样标识。Java中的异常处理就是一个很好的例子-许多人会明确地编写类似的代码作为设计模式(如果它不是核心语法的一部分)。

但是要集中讨论这个问题-您不想在语言中添加太多设计模式的原因有很多:

  • 不必将它们添加为语言构造-所有设计模式都可以通过其他方式实现
  • 这会使语言复杂化 -这是一个坏主意,因为它会使语言更难学习,使编译器和工具更难于编写
  • 存在许多设计模式的替代实现方法。选择一种方法并将其作为核心语言的一部分加以祝福可能会导致人们在其他方法上使用该方法(在某些情况下可能会更好)
  • 在任何情况下,过度依赖设计模式可能都是一个坏主意-语言设计师可能意识到他们不应该进一步鼓励他们。

同样,如果您使用具有元编程功能的足够强大的语言(例如Lisp),则可以自己扩展该语言以实现任何设计模式,这相对容易。如果可以轻松地使用5行宏添加自己的代码,则根本不需要核心语言中的任何模式。


4

为什么不将最常用的设计模式(MVC,工厂,策略等)添加到语言构造中?

在没有特定语言支持的情况下,大多数模式都可以用大多数编程语言实现。以Java中的MVC为例:

  • 您可以直接对其进行编码。
  • 您可以使用应用程序生成器来实现它...并同时照顾很多其他样板。
  • 您可以使用“框架”库类来实现它。
  • 您可以使用注释以及静态或运行时注释处理来实现它。

考虑到所有这些选项,直接扩展语言几乎没有价值。而且有许多“缺点”:

  • 这可能会使语言语法混乱,(可能)使新手程序员的工作变得更加艰难。
  • 这将倾向于使语言规范更大,更复杂,从而使语言实现者更难。(当然,规格越大,错误和不一致的可能性就越大。)
  • 总是会有压力添加另一种模式,从而导致语言稳定性问题。
  • 通过支持语言中的特定模式,您可以硬性地采用特定的方式来支持这些模式,这可能不适合某些应用程序。

4

他们是。

在成为C语言构造之前,函数是汇编代码中的设计模式。

在虚拟函数成为C ++中的乱码构造之前,虚拟函数是C中的一种设计模式。

但是,需要权衡取舍。如果该模式涉及样板代码(甚至两个关键字)的产生,则表明这将是有用的语言功能。但是,如果模式简单明了,例如 C的“ for(int i = 0; i <10; i ++)”,对于每个人以相同的方式编写仍然有用,但是它的长度并不比“ for i = 0 to 10”长,并且具有显着的优势很明显如何更改它以使循环略有不同。


3

阅读“四人帮”一书,就会清楚地知道:

  1. 本书中的设计模式实际上是用其他OO语言编码的众所周知的Smalltalk约定。
  2. 因此,这些模式不能包含在OO语言中-这将在这些语言中重新实现Smalltalk-最好直接使用smalltalk
  3. 设计模式之所以有用,是因为它们不强调当前使用的语言的作用,而专注于语法以外的其他问题。在语言中对这些模式进行编码将失去设计模式的这一功能。
  4. 上述问题的真正问题在于,它错过了编写软件不仅与学习语言有关的观点。与直接提供的语言保持足够的距离,并专注于当前要求,这一点很重要。

2

因为使用用户代码可以很好地实现设计模式。他的示例仅是因为它是PHP,才发生了,但是如果您实际上需要性能,则可以使用另一种语言或使用HipHop或其他工具。

语言功能很复杂,既要指定又要实现,并且仅出于“当前成语是X”的目的创建一个语言功能是没有道理的。您几乎根本不会保存任何有意义的用户代码。


0

嗯,这个问题过时了,​​但我不同意很多答案,具体取决于您在语义表盘上的哪里设置了“设计模式”,包括已接受的答案。

从GoF设计模式书的意义上来说,这要看情况了。例如,MVC(实际上不是GoF模式,而是适合那种模式),完全不适合表达为大量使用的语言构造(尽管对于特定的PHP项目可能有意义)。作为一种架构模式,主题会不断变化,并且会针对不同的情况对主题进行多种合法的解释(尽管到目前为止,许多主题都偏离了MVC,所以可能不再将其称为MVC)。例如,在网络上,http障碍使它显得有些尴尬,这取决于您是否要在等式中包括客户端(无疑是痛苦的),以及您是否正在从更多角度考虑“视图”适当严格地从服务器端角度进行。

另一方面,迭代器是一个非常笼统的概念,可以以多种方式应用于多种构造。

应当确定事物是否属于核心语言设计的界限,即使是服务器端特定于网络的语言,也就是IMO,这是事物跨越界限的要点,因为它可以简化许多事情的数量与执行过于具体但广泛实施的事情(例如为您的架构模式)相比,它更容易。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.