Ist dieses Design übertrieben?

7

Würden Sie die Verwendung einer Schnittstelle und eines Polymorphismus in Erwägung ziehen, um diesen Entwurf zu erweitern, um übertrieben zu werden?

Vorteile

  • Erweiterbar
  • Gekapselt
  • Auto-magisch

Nachteile

  • Viel mehr Code
  • Etwas sperrig zu verwenden (Sie müssen einen anderen Typnamen verwenden, um das unterschiedliche Verhalten zu erhalten)
  • Kann aufgrund virtueller Funktionsaufrufe weniger effizient verwendet werden.

Mein Instinkt ist, dass für diesen speziellen Fall eine einzige if -Anweisung und eine boolesche Flagge die bessere Option ist, aber nicht jeder hat mir zugestimmt.

Was denken Sie ?

Original

%Vor%

Mit einem booleschen Flag erweitert

%Vor%

Erweitert mit Polymorphismus

%Vor%     
Lightness Races in Orbit 23.03.2011, 10:36
quelle

6 Antworten

9

Es hängt davon ab, wofür Sie es verwenden werden. Wenn Sie ein großes Projekt haben und Varianten der Klasse viele Male verwenden, dann ist es sicherlich sinnvoll, es flexibel zu machen.

Eine Faustregel:

  1. Benutze es einmal - halt es einfach.
  2. Benutze es zweimal - Halte es einfach und mache eine Kopie und ändere es nach Bedarf
  3. Drei oder mehr - Generalisieren Sie es und lassen Sie es für alle Fälle funktionieren.

Natürlich gibt es viele Ausnahmen, aber das ist ein Ausgangspunkt.

    
Michael J 23.03.2011, 10:43
quelle
7

Warum kopieren Sie nicht einfach den Dateideskriptor ? Auf diese Weise können Sie, wenn das Objekt zerstört ist, einfach schließen () und das Betriebssystem den Rest erledigen lassen:

%Vor%

Das Hinzufügen eines booleschen Flags dafür erfindet ein Rad. Und mit Polymorphie baut man einen fliegenden Helikopter.

    
Septagram 23.03.2011 10:47
quelle
1

Ich stimme Ihnen zu, dass die boolesche Lösung hier angebracht ist, wenn Sie nicht erwarten, in der Zukunft weitere Funktionen hinzuzufügen.

Eine alternative Lösung wäre die Verwendung des Strategie-Patterns . Dies ähnelt den benutzerdefinierten Löschvorgängen für die Smart-Pointer von Boost.

    
Björn Pollex 23.03.2011 10:45
quelle
1

Ich würde das Über-Engineering in Betracht ziehen. Das zweite Code-Snippet ist viel prägnanter und es ist einfach zu verwenden. Das Verwenden von Flags, um das Eigentum an Objekten zu kennzeichnen, ist nicht völlig idiomatisch, aber es kann ziemlich oft gesehen werden, daher denke ich, dass die meisten Leute die Absicht schnell verstehen werden.

Halten Sie es einfach und dumm.

(Ich würde die polymorphe Lösung bevorzugen, wenn sicher ist, dass in Zukunft weitere Codepfade hinzugefügt werden müssen).

    
Alexander Gessler 23.03.2011 10:46
quelle
1

Ich würde die Schnittstelle bevorzugen. Der Grund dafür ist, dass dem Benutzer der Schnittstelle klar ist, dass es verschiedene Implementierungen geben kann. Vielleicht müssen Sie in einem Monat einen CommandWriter implementieren, der in eine db statt in eine Datei schreibt (sicher, dass Sie sogar die boolesche Version ableiten könnten, aber das ist für den Benutzer nicht so offensichtlich wie eine Schnittstelle).

Auch für Komponententests würde ich sagen, dass die Schnittstelle der sauberere Ansatz ist, da Sie einen Stub für die Klassen implementieren können, die Sie testen möchten und die ICommandWriter verwenden.

Aber wie oben erwähnt, wenn Sie es nur einmal verwenden wollen, nehmen Sie einfach die Version mit dem booleschen Flag.

    
mPopp 23.03.2011 10:49
quelle
1

Im Polymorphie-Code:

%Vor%

Macht es das aber? Wenn es an allen drei Stellen viele Elementfunktionen gibt (Basisklasse und zwei abgeleitete Klassen), dann sind ein besitzender und ein nicht besitzender Schreiber wirklich ziemlich unterschiedliche Bestien. Es ist wahrscheinlich am besten, sie dann in verschiedene Klassen zu trennen, anstatt eine Klasse zu haben, die sich sehr unterschiedlich verhält, je nachdem, welches boolesche Flag nach welchem ​​Konstruktor aufgerufen wurde.

Ich vermute jedoch, dass alle nützlichen Elementfunktionen in der Basisklasse enthalten sind und alle abgeleiteten Klassen die Konstruktion und die Zerstörung ändern. In diesem Fall würde ich eine smart_fd -Klasse wollen, die ein fd enthält und weiß, wie man es entsorgen kann (Sie brauchen zwei Fälle - close close oder gar nichts.% Co_de% erlaubt eine willkürliche Zerstörungsfunktion, aber Sie tun es wahrscheinlich nicht brauche das hier).

Dann haben Sie eines davon in Ihrem CommandWriter und initialisieren das anders, je nachdem, welcher Konstruktor von CommandWriter aufgerufen wird.

Faustregel: Klassen, die Ressourcen verwalten, sollten nichts anderes tun.

    
Steve Jessop 23.03.2011 11:20
quelle

Tags und Links