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

您是否认为在许多模式中,某些动态语言(例如Python)中没有必要(例如,因为它们被动态功能所替代)? />

评论

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

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

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

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

#1 楼

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

自从您提到Python以来,Alex Martelli就该主题做了一个不错的演讲。同样与Python有关的是,有一篇不错的博客文章,演示了惯用的Python中的六种设计模式。

我还保存了一个github存储库,其中包含(最他人)Python中最常见的设计模式的实现。 br />

评论


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

–盖伦努克
2012年7月25日在8:55

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

–mjs
2012年7月29日在21:19



我不清楚是否不需要所有这些模式,因为Lisp是动态的,而是因为其他功能(例如成为强大的功能语言)

– jk。
2012年10月10日14:20

@faif Norvig的论文写于1996年,当时Python还没有迭代器。 (似乎他们到达​​了版本2.1 python.org/dev/peps/pep-0234/。)

–mjs
13-10-15在11:02

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

–狼
2015年1月8日,11:47

#2 楼

无需任何设计模式。用任何一种语言。

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

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

它还有助于将设计模式视为一种思考问题的概念,而不是编写特定的样板代码。而且,作为Java的解决方法的大部分样板都缺乏免费功能和标准功能对象,而这些功能和标准功能对象则用于大多数其他具有它们的语言(例如Python,C#,C ++等)中。

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

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

评论


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

–彼得·托克(PéterTörök)
2012年7月24日在8:39

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

–彼得·托克(PéterTörök)
2012年7月24日在8:44

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

– Jan Hudec
2012年7月24日在9:18

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

– Jan Hudec
2012年7月24日在9:23

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

– Jan Hudec
2012年7月24日在9:25

#3 楼

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

评论


好吧,您仍然需要不同的工厂。您只是不需要接口定义。

– Stefano Borini
2012年7月24日14:26



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

– spookylukey
17年12月29日在10:41

#4 楼

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

由于Python不会强迫您对所有内容使用类,因此您可以只使用全局数据结构。该全局数据结构可以由一个实例管理,但是您不必控制该类的实例化,只需在import上创建实例,然后将其留在该实例上即可。被替换为模块。 python中的模块本质上就是Singletons。 python解释器一次创建一次。

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

评论


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

–丹
2012年7月24日在8:00

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

– Jan Hudec
2012年7月24日在8:00

而且在Python中,我们从来没有打扰过它,因为从来没有要解决的问题。

–马丁·彼得斯(Martijn Pieters)
2012年7月24日在8:12

“ Python不会强迫您对所有对象使用对象”并非如此。它并不像Java中那样令人讨厌,但是仍然,在Python中,所有东西都是对象。甚至模块也是一个对象。

–vartec
2012年7月24日在10:37

@Darthfett:我很清楚len的工作方式; Guido在这里做出了明确的选择。我的观点是证明Python并不是纯OOP语言。这是一种实用的语言。我喜欢这样。

–马丁·彼得斯(Martijn Pieters)
2012年7月24日14:58

#5 楼

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

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

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

评论


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

–盖伦努克
2012年7月24日在8:49

#6 楼

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

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

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

因此,您可能会寻找其他特征,这些特征可使现代动态语言(或诸如Lisp之类的古老语言)更强大,可渲染这些经典设计模式中的一些无关紧要。

#7 楼

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

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

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

#8 楼

我会说模式总是与语言相关的。
大多数python模式看起来像GoF中定义的模式,这是因为Python的OOP,也就是说OOP不像OOP(没有两种语言定义对象及其操作方式100 %相似)。
准确回答您的问题:模式仅在需要时才是必需的。如果不需要它们,则不必使用它们(如Jan Hudec所说)。

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