在动态语言(如Python)中是否有不需要的设计模式?


98

我已经开始阅读GoF的设计模式书。有些模式看起来非常相似,只是概念上的差异很小。

您是否认为在许多模式中,在像Python这样的动态语言中,有些是不必要的(例如,因为它们已被动态功能替代)?


1
有点有趣的问题,因为它暗示着语言选择可以有效替代代码构造。
joshin4colours 2012年

3
不是答案,而是相关的-我认为GoF设计模式与可以从中提炼出来的一些一般原则和特定的模式一样重要。我并不是说要有模式的想法(尽管那肯定很重要),而是要允许以违反天真的OOP原则的某些方式使用类。例如,存在许多模式,其中“形状”很明显不会“绘制自身”,或者至少将工作的某些方面委托给其他对象。我认为该课程对于支持OOP的任何语言都很重要。
2012年

非常有趣的问题。我希望我可以+5而不是+1。
MathAttack 2012年

1
在c2处还可以看到设计模式缺少语言功能,设计模式缺少语言功能。它甚至不是“动态语言”的问题。最简单的示例是迭代器模式,该模式在python,perl(甚至Java)中并不重要。

Answers:


92

彼得·诺维格(Peter Norvig)展示了GOF书中发现的23种设计模式中的16 种在动态语言中不可见的或更简单的(他专注于Lisp和Dylan)。

自从您提到Python以来,Alex Martelli对该主题做了很好的介绍。也与Python有关,有一篇不错的博客文章,演示了惯用的Python中的六种设计模式

我还保留了一个github存储库,其中包含(由其他人执行)Python中最常见的设计模式


大!那将是一个可以解决的问题:)我希望每个人都清楚地理解了这个问题。
Gerenuk

2
根据Norvig的说法,由于使用了宏(Python没有此功能),16个中的2个(解释器和迭代器)“不可见或更简单”。
mjs 2012年

1
对我来说还不是很清楚,不需要所有这些模式是因为lisp是动态的,而是因为其他功能,例如成为强大的功能语言
jk。

@mjs迭代器是Python的内置功能。
sakisk

1
通过更改无意义的链接标题演示演示存储库,甚至可以稍微改善这个好答案-它们比这里要好得多,但是,您知道... :-)
Wolf

59

无需任何设计模式。任何语言。

我倾向于遇到很多人,他们阅读了设计模式,然后认为他们应该在各处使用它们,从而编写了许多代码。结果是实际的代码被埋藏在大量的接口,包装器和层下,并且很难阅读。这是设计模式的错误方法。

存在设计模式,以便在遇到问题时可以方便地使用一些有用的惯用语。但是,在确定问题之前,切勿应用任何模式。保持简单愚蠢永远是最高的管理原则。

它还有助于将设计模式视为思考问题的概念,而不是要编写的特定样板代码。而且,作为Java的变通办法,很多样板都缺少在大多数具有其他功能的其他语言(例如Python,C#,C ++等)中使用的免费功能和标准功能对象。

我可能会说我有一个访问者模式,但是在任何具有一流功能的语言中,它都只是一个带有功能的功能。除了工厂类,我通常只有工厂功能。我可能会说我有一个接口,但是那只是用注释标记的几个方法,因为不会有其他实现(当然在python中,接口总是只是注释,因为它是鸭子类型的)。我仍然将代码称为使用模式,因为这是一种考虑模式的有用方法,但是在我真正需要它之前,不要真正键入所有内容。

因此,将所有模式学习为概念。忘记具体的实现。在现实世界中,即使只是在Java中,实现也有所不同,并且应该有所不同。


28
您的开幕词过于简单化了。的确,模式是有代价的,因此不应仅仅为了它而盲目使用。但是在正确的位置,它们可以提供很大的帮助。是的,它们是特定于语言的- 在某些语言中某些模式是不必要的,因为语言本身支持更好的方法。但这与您的开庭要求相去甚远。
彼得Török

2
Btw Visitor并没有完全被高阶函数取代-它是一种以本身不支持它的语言(例如C#和C ++)实现双重调度的解决方案。(而且确实应该非常谨慎地使用它-我认为它是最不可思议和最昂贵的模式之一,其用法是恕我直言,以至于很难证明我自己到目前为止从未使用过。)
PéterTörök2012年

14
好吧,您永远不需要模式。您需要解决的问题。如果您不知道它的任何模式,您仍然可以解决它,这将需要更多的思考,并且您可能会想出一种与某种模式匹配的解决方案,或者一种与之不匹配的解决方案。了解这些模式只会使其变得更容易。
Jan Hudec 2012年

3
@Gerenuk:是的,但重点是,这些模式不是特定于语言的,而是针对您的。您通常会发现,使用python中的不同工具更容易实现某些模式,但是通常存在相同的概念。
Jan Hudec 2012年

4
@PéterTörök:访客没有被任何东西取代。关键是,在不同情况下可以使用不同的工具来实现相同的概念,但是我仍然认为它是相同的模式。
Jan Hudec 2012年

13

在鸭子类型的语言(例如Python)中,抽象工厂模式是不必要的,因为它实际上已内置在该语言中。


10
好了,您仍然需要不同的工厂。您只是不需要接口定义。
Stefano Borini 2012年

1
如果您有课程,那么您已经有工厂。类是一流的对象,可以在任何地方传递,并且可以简单地调用以创建对象(与Java不同)。您不需要创建其他任何东西。如果您想要的不是默认构造函数,只需创建某种以某种方式包装构造函数的lambda / callable。
spookylukey

13

想到的唯一一个就是Singleton模式。

由于Python不会强制您对所有内容都使用类,因此您只能使用全局数据结构。该全局数据结构可以由一个实例管理,但是您不必控制该类的实例化,只需在import上创建实例,然后将其保留在该实例上即可。

通常,python中的Singleton被模块替换。python中的模块本质上就是Singletons。python解释器只会一次创建一次。

我曾经在Python中一次或多次使用过的Design Patters中的所有其他模式,您会在整个Python标准库和Python本身中找到它们的示例。


2
这些天真的不是反模式吗?
2012年

16
Singleton是一种反模式。所有语言。它是为解决几个不相关的问题而创建的,两者都不是很好的匹配方式(请注意,即使Java也具有静态成员,每个类都存在一次,因此您不需要该实例)。
2012年

1
而且在Python中,我们从来没有理会它,因为从来没有要解决的问题。
马丁·彼得

1
“ Python不会强迫您将对象用于所有内容”不是真的。它并不像Java中那样令人讨厌,但在Python中,一切都是对象。甚至模块也是一个对象。
vartec

3
@Darthfett:我很清楚它是如何len工作的。Guido在这里做出了明确的选择。我的观点是证明Python不是纯OOP语言。这是一种实用的语言。我喜欢这样。
马丁·彼得

8

设计模式是针对程序员的,而不是针对语言的。程序员倾向于使用模式来帮助他们理解手头的问题。绝对没有必要使用设计模式,但是可以使用它来简化您尝试做的事情。

Python(特别是鸭子类型)确实提供了许多常见模式和实践的终结,并且某些模式(隐私,不变性等)带来的许多限制仅在程序员同意不破坏它们的范围内成立。 。但是,只要程序员参与其中,它们就可以工作。即使是假想的墙壁将门框住,门仍然是一扇门。

Python被认为是“多范式”语言。您可以使用所需的任何模式。这是故意的。例如,它提供了复杂的类层次结构,即使它们是完全不必要的并且有些人为的。但是对于某些人来说,特定的抽象是有帮助的。不是因为问题需要它,而是因为程序员需要。所以你去了。


那当然很有趣。那么,由于Python中有更好的方法,您特别是指哪种模式可能会忘记呢?
Gerenuk

4

最初的“设计模式”书记录并命名了一些常见的惯用法,这些惯用法在命令式,面向对象的语言(例如C ++和Smalltalk)中有用。但是Smalltalk是一种动态类型的语言,因此严格来说,它不是动态的。

但是,您的问题的答案仍然是“是”:其中一些设计模式与现代动态类型化语言无关。更一般地,将有不同语言的不同设计模式,尤其是不同种类的语言。

重申一下:“设计模式”只是编程习惯用语的名称:解决常见问题的常用解决方案。不同的语言需要不同的习惯用法,因为一种语言的问题对另一种语言可能是微不足道的。从这个意义上讲,设计模式倾向于指出它们所应用的语言中的弱点。

因此,您可能会寻找其他功能,这些功能使现代动态语言(或诸如Lisp之类的古老语言)更强大,从而使某些经典设计模式变得无关紧要。


1

设计模式是解决特定问题的方法。如果未解决问题,则解决该问题的模式将毫无用处。

人们试图在任何地方适应设计模式,就好像在项目中包含设计模式是一种最佳实践。那是另一回事。您遇到可以通过工厂模式解决的问题吗?凉。适应它。不要查找您的代码,并尝试找到合适的位置来实现单例(或工厂,立面或其他任何东西)。

也许Python有其自己的设计模式,但Java和.NET人士无法使用(由于这些语言的性质)?


1

我会说模式总是与语言相关的。多数python模式看起来像GoF中定义的模式,这是因为Python的OOP,也就是说OOP不像OOP(没有两种语言定义对象,并且它们的操作100%相似)。

因此,毫无疑问,有些模式将不能按“原样”应用,有些模式可能没有意义,而有些模式可能仅对Python有意义。

准确回答您的问题:仅在需要时才需要模式。如果不需要它们,则不必使用它们(如Jan Hudec所说)。

此外,存在比GoF中提到的模式更多的模式。在Wikipedia中查看其他模式

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.