Gibt es ein denkbares Entwurfsmuster für ein objektorientiertes Programm? Ich frage dies, weil ich vor kurzem eine Implementierung einer Door
Klasse mit a gesehen habe Lock
. Es war Teil eines Tests und die Antwort besagte, dass der Code dem Null-Objektmuster folgt:
class Lock
{
public:
virtual void close() = 0;
virtual void open() = 0;
virtual bool is_open() const = 0;
virtual ~Lock() { }
};
class DummyLock
: public Lock
{
private:
DummyLock();
DummyLock(const DummyLock&) = delete;
DummyLock& operator=(const DummyLock&) = delete;
private:
void close() { }
void open() { }
bool is_open() const { return true; }
public:
static DummyLock m_instance;
};
class Door
{
public:
Door() : m_lock(DummyLock::m_instance) { }
Door(Lock &lock) : m_lock(lock) { }
public:
Lock& get_lock() const { return m_lock; }
private:
Lock &m_lock;
};
Das ließ mich denken: Dieser Code folgt einem guten Entwurfsmuster, obwohl die Beschreibung so einfach ist (diese Klasse entwirft eine Türklasse mit einem Schloss). Wenn ich also komplexeren Code schreibe, sollte es immer ein Entwurfsmuster geben, das ich habe folge ich?
design
design-patterns
object-oriented
object-oriented-design
user2030677
quelle
quelle
Antworten:
Lieber Gott NEIN!
Ich meine, Sie können weitermachen und sagen, dass jeder Zufallscode einem zufälligen XYZ-Muster folgt, aber das ist nicht nützlicher, als dass ich behaupte, der König meines Computerstuhls zu sein. Niemand weiß wirklich, was das bedeutet, und selbst diejenigen, die dies tun, werden meinen Anspruch nicht genau respektieren.
Entwurfsmuster sind ein Kommunikationswerkzeug, mit dem Programmierer anderen Programmierern mitteilen können, was getan wurde oder was getan werden sollte, ohne dass sie sich ein wenig wiederholen müssen. Und da es sich um Dinge handelt, die häufig vorkommen, sind sie nützliche Konzepte für Programmierer, um zu lernen, "hey, es scheint immer so, als würde XYZ entstehen, weil es gut / nützlich ist".
Sie ersetzen nicht die Notwendigkeit, dass Sie selbst nachdenken, die Muster für das vor Ihnen liegende einzigartige Problem anpassen oder alle unvermeidlichen Dinge erledigen, die nicht in schöne Eimer passen.
quelle
the_cult
(tm) ist genauso gefährlich.Nein.
Das hat die Viererbande (die ursprünglich Designmuster populär gemacht hat) in ihrem Buch dazu gesagt :
Das Beispiel, das Sie zeigen, macht eigentlich nicht viel (ich glaube nicht, dass es dazu gedacht war, ich denke, es war nur als Beispiel gedacht). An sich benötigt es kein Null-Objektmuster. Im Kontext eines größeren Programms könnte es sein.
Der falsche Ansatz geht davon aus, dass es gut sein muss, nur weil es als "Entwurfsmuster" bezeichnet wurde, und dann nach mehr Stellen Ausschau zu halten, an denen mehr Muster eingefügt werden können. Verwenden Sie diese, wenn sie zum Programm passen und tatsächlich ein Problem für Sie lösen.
quelle
Nein. Designmuster sind genau das: Muster in Beziehungen zwischen Objekten. Mit anderen Worten, Beziehungen, die häufig genug genutzt und wiederverwendet werden, dass jemand sagte: "Hey, wir scheinen das sehr oft zu tun, geben wir ihr einen Namen." Die Liste der Entwurfsmuster wurde zu Beginn von OOP nicht auf einmal festgelegt und dann von GOF ! Sie wurden entdeckt und schließlich dokumentiert und dann durch das Buch populär gemacht.
Ein großer Vorteil von Entwurfsmustern besteht jedoch darin, dass sie das Nachdenken über Softwareentwurf auf einer höheren Ebene erleichtern. Sie können sich keine Gedanken über Implementierungsdetails machen und mehr über das Gesamtbild nachdenken. In diesem Sinne befreien sie dich von den Kleinigkeiten, aber sie können dich auch auf die gleiche Weise einschränken, wie die Art, wie du dich ausdrückst, durch die Wörter, die du kennst, eingeschränkt werden kann. So kann es eine Zeit kommen , wenn es ist ein Musterentwurf für die meisten von dem, was Sie tun , nur weil die Muster , die Sie wissen , sind die Begriffe , in denen Sie denken. Halten Sie die Augen offen für Fälle, in denen Sie möglicherweise ein Muster missbrauchen und über bessere Vorgehensweisen nachdenken müssen.
Beachten Sie auch, dass Sie in der Praxis ein bestimmtes Entwurfsmuster häufig nicht so sehr implementieren, als dass Sie das Muster in einem vorhandenen Code wie einem Objektframework erkennen. Wenn Sie sich mit gängigen Entwurfsmustern auskennen, können Sie leichter lernen, wie ein Framework verwendet werden soll, da Sie die Beziehungen zwischen Klassen in Begriffen sehen können, die Sie bereits verstanden haben.
quelle
Entwurfsmuster haben zwei Vorteile
Die Ziele eines jeden Programms sollten sein
Wenn alles gesagt ist, beachten Sie, dass jeder Verweis auf OO-Designmuster "sie sind einfach gut in der Arbeit." Sie sind nicht perfekt, füllen aber sehr effektiv eine Nische. Verwenden Sie sie, wenn sie arbeiten, vermeiden Sie sie, wenn sie es nicht tun.
Als Beispiel für "komplexen Code" nehmen Sie, wie Sie in Ihrer Frage erwähnt haben, eine Skriptsprache, die ich geschrieben habe. Das meiste davon ist OO mit Designmustern überall. Als ich jedoch den Müllsammler schrieb, ließ ich kurzerhand alle Täuschungen von OO fallen, weil die besonderen Dinge, die ich tun musste, besser als altmodisches Bit-Bashing modelliert waren. Es gibt kein OO-Muster in der gesamten Sache, bis es zum Schreiben von Finalisierern kam, wo OO wieder anfing, ein nützliches Modell zu sein. Ohne Pomp oder Umstände wurde der Code plötzlich wieder auf die Verwendung von OO-Techniken umgestellt.
Verwenden Sie Entwurfsmuster, wenn sie Ihr Produkt verbessern. Vermeiden Sie sie, wenn sie Ihr Produkt verschlechtern.
quelle
Ich werde mich dem Trend ein wenig widersetzen, weil die Antwort subtiler ist, als andere Antworten es zulassen. Jede Klasse, die Sie schreiben, sollte kein Entwurfsmuster verwenden, aber die meisten nicht trivialen Programme, die Sie schreiben, sollten dies wahrscheinlich tun.
Ein nicht-triviales Programm ohne Designmuster zeigt Folgendes an:
Beide Szenarien sind höchst unwahrscheinlich, keine Beleidigung.
Das bedeutet nicht, dass das Entwurfsmuster Ihr Entwurf bestimmen sollte, oder dass Sie eines wahllos einfügen sollten, da Sie der Meinung sind, dass es schlecht aussehen wird, wenn Sie dies nicht tun. Das falsche Designmuster ist schlimmer als keines.
Das heißt, Sie sollten einen Mangel an Designmustern in Ihrem Gesamtprogramm als Code-Geruch betrachten. Etwas, das Sie veranlasst, einen zweiten Blick darauf zu werfen und eine Neubewertung vorzunehmen, wenn Ihr Design nicht sauberer sein könnte. Wenn Sie sich zu diesem Zeitpunkt dafür entscheiden, Designmuster aus einem Programm herauszulassen, sollte dies eine bewusste, informierte Entscheidung sein, nicht ein Zufall.
Sie sagen beispielsweise nicht: "Ich muss eine Tür und ein Schloss modellieren. Welches Entwurfsmuster soll ich verwenden?" Wenn Sie es jedoch zuerst entworfen haben, ohne Designmuster zu verwenden, sollten Sie anschließend gefragt werden, ob es ein Designmuster gibt, mit dem Sie diese verwalten können.
Sieh den Unterschied? Es ist eine subtile, aber wichtige Unterscheidung.
quelle
Gebrochene Frage. Lassen Sie mich eine neuartige Definition des Entwurfsmusters geben, die einen Großteil des von GoF verursachten Schadens rückgängig machen würde: Ein Entwurfsmuster ist eine gute Codierungspraxis . Das ist es.
Jedes einigermaßen komplexe Modul enthält mehrere Entwurfsmuster. Jedes Mal, wenn Sie im Cache speichern, handelt es sich wahrscheinlich um ein Fliegengewichtmuster, aber ich werde Ihren Programmiergrad nicht widerrufen, wenn Sie ihn nicht so nennen. Jedes Mal, wenn Sie einen Rückruf erhalten, befinden Sie sich in einem Ereignis- / Feuer- / Rückrufmuster. usw. Wenn Sie das Wort "statisch" haben, haben Sie einen Singleton. Wenn Sie einen statischen Konstruktor haben, haben Sie ein Factory-Muster. Wenn eine Ressource an Ihr Modul übergeben wird, verwenden Sie die Abhängigkeitsinjektion.
"Design Pattern" ist ein gebrochener Begriff, der von GoF schlecht populär gemacht wird. Es hört sich so an, als wären alle Patterns auf dem gleichen Level, oder Sie sollten den vom Arzt empfohlenen 3 bis 5 pro Klasse verwenden. Jedes Mal, wenn Sie etwas richtig machen, was jemand anderes richtig gemacht hat, ist es ein Entwurfsmuster . A
for(;;)
ist ein übliches Muster, das zum Beispiel zur Darstellung einer Endlosschleife verwendet wird.Sie sollten nicht versuchen, ein paar Designmuster zu lernen. Programmierkenntnisse werden nicht durch Entwurfsmuster indiziert! Sie sollten vielmehr lernen, wie Sie guten Code schreiben, indem Sie Bücher und Blogs lesen und an Konferenzen in Ihrem Bereich teilnehmen. Wenn Sie beispielsweise bereits die Abhängigkeitsinjektion verwenden, diese jedoch nicht benannt haben, können Sie davon profitieren, immer DI oder ein IoC-Framework zu verwenden. Wenn Sie Schwierigkeiten haben, in Ereignissen und Rückrufen richtig zu programmieren, lernen Sie Haskell, damit Sie mit funktionalen Entwurfsmustern vertraut sind und es einfach wird.
Und wenn Ihre gesamte Klasse als eine große Sache liest, die jemand anderes richtig gemacht hat, warum erfinden Sie dann das Rad neu? Verwenden Sie einfach ihre Sachen.
quelle
for(;;)
idiomatisch? Das ist wahrscheinlich nicht das beste Beispiel für etwas, das jemand "richtig" gemacht hat.while(true)
(oderwhile(1)
) in C, C ++, Java oder C # in meinen 20 Jahren der Programmierung.Sie sollten immer die OO-Entwurfsprinzipien befolgen (z. B. Modularität, Ausblenden von Informationen, hohe Kohäsion usw.). Entwurfsmuster sind eine relativ raffinierte Nische der OO-Entwurfsprinzipien, insbesondere wenn Sie das KISS-Prinzip berücksichtigen .
Muster sind Lösungen für häufig auftretende Designprobleme. Diese Probleme kommen von einer von zwei Stellen (oder einer Mischung aus beiden): dem Problembereich (z. B. Software zur Verwaltung der Humanressourcen in einem Unternehmen) und dem Lösungsbereich . Ein OO-Programm ist eine Instanz innerhalb des Lösungsbereichs (z. B. eine von vielen Möglichkeiten, ein OO-Programm zu entwerfen, um die Verwaltung von HR zu vereinfachen).
Es ist nicht so einfach zu wissen, wann ein Muster zu verwenden ist. Einige Muster befinden sich auf niedriger Ebene, näher an der Codierung und am Lösungsraum (z. B. Singleton, Null-Objekt, Iterator). Andere werden durch Anforderungen im Problembereich motiviert (z. B. Befehlsmuster zur Unterstützung von Rückgängig / Wiederherstellen, Strategie zur Unterstützung mehrerer Eingabe- / Ausgabedateitypen).
Viele Muster ergeben sich aus der Notwendigkeit, künftige Variationen der Software zu unterstützen. Wenn Sie diese Variationen nie vornehmen müssen, kann ein Muster überzeichnet sein. Ein Beispiel wäre die Verwendung des Adaptermusters für die Arbeit mit der vorhandenen externen HR-Datenbank. Sie entscheiden sich für den Einsatz von Adapter, da die aktuelle Datenbank mit Oracle zusammenarbeitet und Sie möglicherweise NoSQL in Zukunft unterstützen möchten. Wenn NoSQL niemals in Ihre Organisation kommt, kann dieser Adaptercode sehr wohl unbrauchbar sein. Siehe YAGNI . Die Unterstützung für Variationen, die niemals auftreten, ist die falsche Verwendung eines Entwurfsmusters.
quelle
Muster sind übliche Lösungen für häufig auftretende Probleme. Wir folgen immer einigen Mustern, die Muster von GoF sprechen die am häufigsten vorkommenden an. Das, um ein gemeinsames Verständnis und einen gemeinsamen Ansatz zu haben, die den Software-Ingenieuren bekannt sind.
Das heißt, meine Antwort ist nein, aber ja, Sie folgen immer einem eigenen Muster. Wie die GoF zu Recht sagt,
Großartiges Zitat.
quelle
Wenn ich Code schreibe, plane ich nicht, so viele Entwurfsmuster wie möglich absichtlich zu verwenden. Aber ich denke, wenn ich unbewusst ein Codierungsproblem bekomme, scheint eines der Designmuster zu passen, und ich benutze es einfach. Und manchmal passt nichts. Was mir wichtiger ist, ist das Schreiben von Code, der die Arbeit erledigt und einfach zu warten und zu erweitern ist.
Hier finden Sie einen Artikel zum Anwenden von OOD-Prinzipien mithilfe von Entwurfsmustern sowie Codebeispiele (in C ++). Es zeigt, wie und wann einige der Entwurfsmuster angewendet werden müssen, um sauberen Code zu schreiben.
quelle