Gibt es Entwurfsmuster, die in dynamischen Sprachen wie Python nicht erforderlich sind?

98

Ich habe angefangen, das Design Pattern Book der GoF zu lesen. Einige Muster scheinen mit nur geringen konzeptuellen Unterschieden sehr ähnlich zu sein.

Denken Sie aus den vielen Mustern heraus, dass einige in einer dynamischen Sprache wie Python unnötig sind (z. B. weil sie durch ein dynamisches Feature ersetzt werden)?

Gerenuk
quelle
1
Eine interessante Frage, da dies impliziert, dass die Sprachauswahl Codekonstrukte effektiv ersetzen kann.
Joshin4colours
3
Keine Antwort, aber relevant - Ich dachte, dass die GoF-Designmuster für einige allgemeine Prinzipien, die daraus abgeleitet werden können, genauso relevant sind wie für die spezifischen Muster. Ich meine nicht die Idee eines Musters (obwohl das sicherlich von Bedeutung ist), sondern die Erlaubnis, Klassen auf bestimmte Weise zu verwenden, die gegen naive OOP-Prinzipien verstoßen. Es gibt zum Beispiel viele Muster, bei denen "die Form" sich nicht "von selbst zeichnet" oder zumindest einen Teil des Auftrags an ein anderes Objekt delegiert. Ich denke, dass Unterricht in jeder Sprache wichtig ist, die OOP unterstützt.
Steve314
Sehr interessante Frage. Ich wünschte, ich könnte +5 statt +1.
MathAttack
1
Ein Blick auf Are Design Patterns Missing Language Features und Design Patterns Are Missing Language Features bei c2. Es ist nicht einmal eine Frage der "dynamischen Sprache". Das einfachste Beispiel ist das Iteratormuster, das in Python, Perl (und sogar Java - nicht dynamisch) trivial ist.

Antworten:

92

Peter Norvig demonstriert, dass 16 der 23 im GOF-Buch gefundenen Designmuster in dynamischen Sprachen unsichtbar oder einfacher sind (er konzentriert sich auf Lisp und Dylan).

Seit Sie Python erwähnt haben, gibt es eine schöne Präsentation von Alex Martelli zu diesem Thema. Ebenfalls mit Python verwandt ist ein netter Blog-Beitrag, der sechs Designmuster in idiomatischem Python demonstriert .

Ich verwalte auch ein Github-Repository mit Implementierungen (von anderen Leuten) der gängigsten Entwurfsmuster in Python .

Sakisk
quelle
Toll! Das wäre eine perfekte Antwort :) Ich wünschte, jeder hätte die Frage so klar verstanden.
Gerenuk
2
Laut Norvig sind 2 der 16 (Interpreter und Iterator) aufgrund von Makros (die Python nicht hat) "entweder unsichtbar oder einfacher".
mjs
1
Mir ist nicht klar, dass all diese Muster nicht benötigt werden, weil lisp dynamisch ist, sondern weil es sich um eine starke funktionale Sprache handelt
jk.
@mjs Iteratoren sind eine eingebaute Funktion von Python.
Sakisk
1
Diese große Antwort kann sogar leicht verbessert , indem die etwas sinnlos Link Beschriftungen zu ändern zeigt , Präsentation und Repository - sie weit besser sind dann hier , aber, wissen Sie ... :-)
Wolf
59

Es sind keine Entwurfsmuster erforderlich. In jeder Sprache.

Ich stoße auf eine Menge Code, der von Leuten geschrieben wurde, die sich mit Designmustern befasst haben und dann der Meinung sind, dass sie sie überall verwenden sollten. Das Ergebnis ist, dass der eigentliche Code unter Tonnen von Schnittstellen, Wrappern und Layern verborgen bleibt und ziemlich schwer zu lesen ist. Das ist eine falsche Herangehensweise an Designmuster.

Entwurfsmuster sind vorhanden, sodass Sie ein Repertoire nützlicher Redewendungen zur Hand haben, wenn Sie auf ein Problem stoßen. Sie sollten jedoch niemals ein Muster anwenden, bevor Sie das Problem identifiziert haben. Halte es einfach Dumm sollte immer das überlegene Prinzip sein.

Es ist auch hilfreich, sich Entwurfsmuster als ein Konzept vorzustellen, um über das Problem nachzudenken, anstatt spezifischen Code zu schreiben. Und über einen Großteil des Boilerplates als Workaround für Java fehlen freie Funktionen und Standardfunktionsobjekte, die Sie in den meisten anderen Sprachen verwenden, in denen sie enthalten sind (wie Python, C #, C ++ usw.).

Ich könnte sagen, dass ich ein Besuchermuster habe, aber in jeder Sprache mit erstklassigen Funktionen wird es nur eine Funktion sein, die eine Funktion übernimmt. Anstelle der Fabrikklasse habe ich normalerweise nur eine Fabrikfunktion. Ich könnte sagen, ich habe eine Schnittstelle, aber dann sind es nur ein paar Methoden, die mit Kommentaren markiert sind, da es keine andere Implementierung gibt (in Python sind Schnittstellen natürlich immer nur Kommentare, weil sie vom Typ Ente sind). Ich spreche immer noch davon, dass der Code das Muster verwendet, weil es eine nützliche Möglichkeit ist, darüber nachzudenken, aber tippe nicht wirklich alles ein, bis ich es wirklich brauche.

Lernen Sie also alle Muster als Konzepte . Und vergessen Sie die spezifischen Implementierungen. Die Implementierung variiert und sollte in der realen Welt variieren, auch nur in Java.

Jan Hudec
quelle
28
Ihre Eröffnungsrede ist extrem vereinfachend. Es ist wahr, dass Muster ihre Kosten haben und daher nicht blind verwendet werden sollten, nur um dies zu erreichen. Aber am richtigen Ort können sie eine große Hilfe sein. Und ja, sie sind sprachspezifisch - einige Muster sind in einigen Sprachen nicht erforderlich, da die Sprache selbst einen besseren Ansatz unterstützt. Aber das ist noch ziemlich weit von Ihrem Eröffnungsanspruch entfernt.
Péter Török
2
Btw Visitor wird nicht vollständig durch Funktionen höherer Ordnung ersetzt - es ist eine Lösung, Double Dispatch in einer Sprache zu implementieren, die es nicht von Haus aus unterstützt (wie C # und C ++). (Und es sollte in der Tat sehr sparsam verwendet werden - ich halte es für eines der geheimnisvollsten und kostspieligsten Muster, dessen Verwendung meiner Meinung nach so schwer zu rechtfertigen ist, dass ich es selbst bis jetzt noch nie verwendet habe.)
Péter Török
14
Naja, du brauchst nie ein Muster. Was Sie brauchen, ist ein Problem zu lösen . Wenn Sie kein Muster dafür kennen, können Sie es trotzdem lösen, es wird mehr Nachdenken erfordern und Sie können eine Lösung finden, die mit einem Muster übereinstimmt oder mit einem, das nicht übereinstimmt. Das Kennen der Muster macht es einfach einfacher.
Jan Hudec
3
@Gerenuk: Ja, aber der Punkt ist, dass die Muster nicht sprachspezifisch sind, sie sind für deinen Kopf. Sie werden oft feststellen, dass einige Muster viel einfacher zu realisieren sind und verschiedene Werkzeuge in Python verwenden, aber normalerweise gibt es das gleiche Konzept.
Jan Hudec
4
@ PéterTörök: Besucher wird durch nichts ersetzt. Der Punkt ist, dass dasselbe Konzept in verschiedenen Fällen mit unterschiedlichen Tools implementiert werden kann, aber ich halte es immer noch für dasselbe Muster.
Jan Hudec
13

Abstrakte Factory-Muster sind in Enten-typisierten Sprachen wie Python nicht erforderlich, da sie praktisch in die Sprache integriert sind.

vartec
quelle
10
Nun, Sie brauchen noch verschiedene Fabriken. Sie brauchen nur die Schnittstellendefinition nicht.
Stefano Borini
1
Wenn Sie eine Klasse haben, haben Sie bereits eine Fabrik. Klassen sind erstklassige Objekte und können überall herumgereicht und einfach aufgerufen werden, um ein Objekt zu erstellen (im Gegensatz zu Java). Sie müssen nichts anderes erstellen. Wenn Sie etwas wollen, das nicht der Standardkonstruktor ist, erstellen Sie einfach ein Lambda / Callable, das den Konstruktor irgendwie umschließt.
Spookylukey
13

Das einzige, was mir einfällt, ist das Singleton-Muster.

Da Python Sie nicht zwingt, Klassen für alles zu verwenden , können Sie stattdessen nur eine globale Datenstruktur verwenden. Diese globale Datenstruktur könnte von einer Instanz verwaltet werden, aber Sie müssen die Instanziierung dieser Klasse nicht steuern. Sie erstellen die Instanz nur beim Import und belassen sie dabei.

Meist werden Singletons in Python durch ein Modul ersetzt. Module in Python sind von Natur aus Singletons; Der Python-Interpreter erstellt diese nur einmal.

Alle anderen Muster in Design Patters, die ich in Python verwendet habe, finden Sie in der gesamten Python-Standardbibliothek und in Python selbst.

Martijn Pieters
quelle
2
Ist das heutzutage nicht wirklich ein Anti-Muster?
Den
16
Der Singleton ist ein Gegenmuster . In allen Sprachen. Es wurde entwickelt, um mehrere nicht zusammenhängende Probleme zu lösen, und passt auch nicht gut zusammen (beachten Sie, dass selbst Java statische Mitglieder hat, die einmal pro Klasse existieren, sodass Sie dafür keine Instanz benötigen).
Jan Hudec,
1
Und in Python haben wir uns nie darum gekümmert, da es nie ein Problem gab, das gelöst werden konnte.
Martijn Pieters
1
"Python zwingt Sie nicht, Objekte für alles zu verwenden" Nicht wahr. Es ist einfach nicht unangenehm wie in Java, aber dennoch ist in Python alles ein Objekt. Auch Modul ist ein Objekt.
Vartec
3
@Darthfett: Ich weiß genau, wie es lenfunktioniert. Guido traf hier eine explizite Wahl . Ich möchte zeigen, dass Python keine reine OOP-Sprache ist. Es ist eine pragmatische Sprache. Ich mag es so.
Martijn Pieters
8

Entwurfsmuster sind für den Programmierer, nicht für die Sprache. Programmierer tendieren dazu, Muster zu verwenden, die ihnen helfen, das vorliegende Problem zu verstehen. Ein Entwurfsmuster ist nicht unbedingt erforderlich, kann jedoch hilfreich sein, um das zu vereinfachen, was Sie versuchen.

Python und speziell das Schreiben von Enten bieten ein Ende vieler gängiger Muster und Praktiken, und viele der Einschränkungen, die durch einige Muster auferlegt werden (Datenschutz, Unveränderlichkeit usw.), gelten nur in dem Maße, in dem der Programmierer zustimmt, sie nicht zu brechen . Aber nach wie vor, sie tun arbeiten, solange der Programmierer mitspielt. Eine Tür ist immer noch eine Tür, auch wenn sie von imaginären Wänden eingerahmt wird.

Python wird als eine "Multi-Paradigma" -Sprache angesehen. Sie können beliebige Muster verwenden. Das ist beabsichtigt. Es sieht zum Beispiel komplexe Klassenhierarchien vor, obwohl diese völlig unnötig und ein bisschen künstlich sind. Aber für manche Menschen ist diese bestimmte Abstraktion hilfreich. Nicht weil das Problem es erfordert, sondern weil es der Programmierer tut. Hier bitteschön.

tylerl
quelle
Das ist sicher interessant. Welche Muster meinst du also besonders, die man vergessen könnte, weil es in Python bessere Möglichkeiten gibt?
Gerenuk
4

Das ursprüngliche Buch "Design Patterns" dokumentierte und nannte einige gebräuchliche Redewendungen, die in imperativen, objektorientierten Sprachen wie C ++ und Smalltalk nützlich sind. Smalltalk ist jedoch eine dynamisch geschriebene Sprache, daher kann es nicht ausschließlich darum gehen, dynamisch zu sein.

Die Antwort auf Ihre Frage lautet jedoch immer noch "Ja": Einige dieser Entwurfsmuster sind für moderne dynamisch typisierte Sprachen irrelevant. Im Allgemeinen wird es unterschiedliche Entwurfsmuster in unterschiedlichen Sprachen geben, insbesondere in unterschiedlichen Arten von Sprachen.

Um es noch einmal zu wiederholen: Ein "Entwurfsmuster" ist einfach ein Name für eine Programmiersprache: eine häufige Lösung für ein häufig auftretendes Problem. Unterschiedliche Sprachen erfordern unterschiedliche Redewendungen, da das Problem für eine Sprache für eine andere trivial sein kann. In diesem Sinne weisen Designmuster auf Schwächen in den Sprachen hin, für die sie gelten.

Vielleicht suchen Sie nach anderen Funktionen, die moderne dynamische Sprachen (oder alte wie Lisp) leistungsfähiger machen und einige dieser klassischen Designmuster irrelevant machen.

kommendes Gewitter
quelle
1

Entwurfsmuster sind Möglichkeiten zur Lösung bestimmter Probleme. Wenn ein Problem nicht gelöst wird, hat das Muster der Lösung keine Verwendung.

Die Leute versuchen, Entwurfsmuster überall so anzupassen, als wäre es eine bewährte Methode, Entwurfsmuster in Ihrem Projekt zu haben. Das ist anders herum. Sie stoßen auf ein Problem, das mit einem Fabrikmuster gelöst werden kann? Cool. Passen Sie es an. Schlagen Sie Ihren Code nicht nach und versuchen Sie, den richtigen Ort für die Implementierung eines Singleton (oder einer Fabrik, einer Fassade oder was auch immer ...) zu finden.

Möglicherweise verfügt Python über eigene Entwurfsmuster, die für Java- und .NET-Benutzer (aufgrund der Beschaffenheit dieser Sprachen) nicht verfügbar sind.

Andrzej Bobak
quelle
1

Ich würde sagen, dass Muster immer sprachabhängig sind. Dass die meisten Python-Patterns so aussehen wie die in GoF definierten, liegt an der OOP von Python, dass gesagt wird, dass OOP nicht mit OOP vergleichbar ist (keine zwei Sprachen definieren Objekte und ihre Manipulation ist zu 100% gleich).

Es besteht also kein Zweifel, dass einige Muster "wie sie sind" nicht anwendbar sind, einige ergeben möglicherweise keinen Sinn und einige Muster sind möglicherweise nur für Python von Bedeutung.

Um genau auf Ihre Frage zurückzukommen: Muster sind nur erforderlich, wenn Sie sie benötigen . Sie müssen nicht verwendet werden, wenn sie nicht benötigt werden (wie Jan Hudec bereits sagte).

Darüber hinaus gibt es viel mehr Muster als in GoF erwähnt. Siehe in Wikipedia andere Muster

estani
quelle