Entwurfsmusterfrage

7

Ich bin ein Neuling für die Designmuster und hier ist meine Frage

Wenn wir eine abstrakte Klasse mit wenigen Klassen haben, die sie implementieren, und jede dieser Klassen hat andere Attribute.

Jetzt habe ich eine andere (Manager-Klasse), die ein Array der abstrakten Klasse enthält, und ich möchte eine Suchmethode darin einfügen ... wie kann ich das tun, ohne auf die konkreten Klassen zu werfen?

Ich habe zwei Ideen:

First One : Hinzufügen einer zusätzlichen Ebene von Schnittstellen (dh, anstatt Casting zu konkreter Klasse ich werde auf eine Schnittstelle werfen), die mit dem Code zur Schnittstelle nicht Implementierungsregel geht ... Aber auf diese Weise muss ich, wenn ich eine andere Klasse hinzufüge, eine Schnittstelle dafür erstellen und ich werde auch den Manager (Client) bearbeiten müssen, was nicht sehr gut aussieht.

Zweite Lösung: es sieht etwas komisch aus und benötigt noch Verbesserungen, aber sein Hauptziel ist es, den Manager oder irgendeinen anderen Client mit der abstrakten Klasse arbeiten zu lassen, ohne etwas darüber zu wissen, wer es oder seine Attribute erweitert.

Die Lösung ist wie folgt: Jedes hinzugefügte neue Element muss eine Schnittstelle übersteuern, die es erzwingt, um eine vollständige Beschreibung seiner Felder zu erzeugen, zum Beispiel muss ein Fahrzeugobjekt zurückkehren eine Hash-Karte mit dem folgenden

Feld: {Feldtyp, Feldwert}

Beispiel

  • Modell: {text, "ford"}
  • manufactureDate: {Datum, "01.12.89"}

und jedes Objekt muss auch eine Methode namens compareFields implementieren, die a Hash-Karte wie folgt und vergleichen Sie es mit seinem Feld und geben wahr oder falsch zurück.

jetzt auf diese Weise habe ich viele Probleme gelöst - Für die GUI muss ich nur eine Rendering-Engine für diese hashmap erstellen, die angezeigt werden kann jedes Element ohne zu wissen, was sein Typ ist. (Wieder ist die GUI ein anderer Client für die abstrakte Klasse)

- Für die Suche kann ich eine Hash-Map erhalten, die die Felder enthält, die der Benutzer eingibt Suchen Sie in der Suchmaske nach den abstrakten Elementen und rufen Sie die compare fieldmethod

auf

ich mache immer noch nicht, wie ich das komplexe Objekt behandeln werde (die ein anderes Objekt als seine Attribute haben)

Ich weiß nicht, welche Art von Muster das ist .. es ist nur eine Idee, über die ich nachgedacht habe.

BEARBEITEN: BETONBEISPIEL

wenn ich eine abstrakte Gegenstandsklasse mit einem Auto und einem Bus und einem Boot habe, das es implementiert, und jede dieser Klassen hat andere Attribute .... Wie kann ein Manager zum Beispiel Verkehrsmanager nach einem bestimmten Gegenstand suchen, indem er die abstrakte Klasse benutzt, ohne auf Auto oder Bus zu werfen ... wirklich leid für die lange Frage

    
Ahmed Kotb 17.12.2009, 18:00
quelle

8 Antworten

9

Kapselung

Das OO-Prinzip der Kapselung besagt, dass Ihr Objekt seinen Zustand nicht nach außen hin offen legen sollte. Wenn Ihr Objekt interne Informationen epxosiert, unterbricht es die Kapselung. Was nach OO-Design noch OK ist, ist, das Suchkriterium an das Objekt zu übergeben und es entscheiden zu lassen, ob sie übereinstimmen.

%Vor%

Sie können einen Interator für alle Fahrzeuge verwenden und diejenigen abrufen, die übereinstimmen, ohne die Kapselung zu unterbrechen. Bestimmte Fahrzeugimplementierungen können immer noch nach Bedarf neu implementiert werden.

Besucher

Andernfalls würde ich vorschlagen, dass Sie sich das Muster Besucher ansehen. Die Idee ist dann, das ganze Objekt zu durchlaufen und eine zusätzliche Klasse zu behandeln, die für jeden spezifischen Typ behandelt wird. Dies unterbricht auch die reine Verkapselung (weil das Objekt seine Daten dem Besucher zur Verfügung stellen muss), aber es ist sehr elegant.

%Vor%

Meta-Programmierung

Die Idee des Objekts, die sich selbst beschreibt, ist ein anderes Konzept, das als Meta-Programmierung bezeichnet wird. Die Präsentationsebene untersucht dann andere Objekte, um zu wissen, wie sie damit umgehen sollen. Dies wird traditionell als eine fortgeschrittene OO-Technik betrachtet. Sie könnten benutzerdefinierte Anmerkungen erstellen, um das Feld Ihrer Klasse zu beschreiben, damit die Präsentationsebene das entsprechende Label dynamisch darstellen kann. Dieselbe Idee wird zum Beispiel bei Hibernate-Annotationen verwendet. Meta-Programmierung muss sorgfältig durchgeführt werden, sonst laufen Sie in ein anderes Problem.

Installation von

Verwenden Sie insteanceof ist auch eine Form der Introspektion (weil Sie das Objekt nach seiner Klasse fragen) und wird normalerweise abgeraten. Nicht weil es an sich falsch ist, sondern weil es dazu neigt, missbraucht zu werden. Wenn möglich, verlassen Sie sich auf traditionelle OO-Prinzipien. Die Verwendung von instanceof missbräuchlich ist ein Code-Geruch .

Alles in allem würde ich empfehlen, einen Besucher für die Suche zu verwenden und Meta-Programmierung für die Präsentationsebene nicht zu verwenden und stattdessen eine einfache Seite pro Fahrzeugtyp zu erstellen. p>     

ewernli 17.12.2009, 19:00
quelle
6

Ok, also erweitern Sie die Klasse, anstatt eine Schnittstelle zu implementieren. Wenn Sie Klassen Bus, Auto, LKW, Zug und alle IVehicle implementiert haben, die eine Funktion benötigen, die einen sortierbaren / durchsuchbaren Wert zurückgibt, könnten Sie alle als Typ IVehicle referenzieren und diese Methode für alle aufrufen .

  

ActionScript 3-Code:

%Vor%

und

%Vor%

Sie müssen getSpeed ​​() und getOtherSortableValue () in der Klasse Auto definieren und können sie entweder als Auto oder als IV-Fahrzeug bezeichnen. Da alle Verkehrsmittel in meinem Beispiel IVehicle implementieren, können Sie diese beiden Funktionen aufrufen, solange Sie sie als IVehicles bezeichnen.

    
Tegeril 17.12.2009 18:21
quelle
4

Sie scheinen zu beschreiben, was Steve Yegge das universelle Designmuster nennt >

Die Verwendung von Schlüssel / Wert-Paaren mit einer GUI kann in einfachen Fällen funktionieren, aber es ist schwer, dafür zu sorgen, dass es gut aussieht. Wenn Ihre Objekthierarchie nicht tief ist und sehr erweiterbar sein soll, sollten Sie für jede konkrete Klasse ein separates Formular erstellen, da dies weniger Arbeit bedeutet und besser aussieht. Sie können weiterhin freigegebene GUI-Komponenten wiederverwenden, daher sollte das Hinzufügen einer neuen konkreten Klasse ziemlich einfach sein.

    
RossFabricant 17.12.2009 18:00
quelle
2

Das scheint mir eine Art "zentralisiertes" Repository-Muster zu sein. Ich denke nicht, dass das eine gute Idee ist.

Was Sie empfehlen, ist, dass Sie statt einer zentralisierten generalisierten Suche mehrere spezialisierte Repositories haben sollten: eines für Autos, eines für Boote, eines für Flugzeuge usw.

Jedes der Repositories kennt die Details der jeweiligen Objekte. Sie können dann allgemeine Operationen zwischen diesen spezialisierten Repositorys, einer Repository-Basisklasse oder -Schnittstelle ausschließen. Wenn Sie sich nicht um die Details kümmern, verwenden Sie die Basis-Repository-Schnittstelle. Wenn Sie sich um die Details kümmern, verwenden Sie das spezialisierte Repository.

Hier ist ein simples Beispiel in Java (Ich verlasse Getter / Setter aus Gründen der Kürze - nicht mache deine Felder öffentlich):

%Vor%     
R. Martinho Fernandes 17.12.2009 18:35
quelle
2

Das klingt wie ein Job für das Besuchermuster. Sie haben eine Sammlung von abstrakten Objekten und Sie wissen nicht, was jeder ist. Mit Visitor können Sie über alle Objekte iterieren und für jede eine spezifische Aktion ausführen. Das GOF Patterns-Buch bietet gute Details zum Besuchermuster, aber ich werde versuchen, hier ein gutes Java-Beispiel zu bieten.

%Vor%

Ja, auf den ersten Blick können Sie der Vehikel-Klasse einfach eine Suchmethode hinzufügen und diese für jedes Mitglied der Liste aufrufen, aber das Besuchermuster erlaubt es Ihnen, mehrere Operationen über die Liste der Fahrzeuge zu definieren Ich muss für jedes Fahrzeug eine neue Methode hinzufügen.

Ein Nachteil des Besuchermusters besteht jedoch darin, dass der Besucher selbst geändert werden muss, wenn Sie eine neue Objektklasse hinzufügen. Wenn Sie in diesem Beispiel ein RocketShip-Fahrzeug zum System hinzufügen, müssen Sie dem Besucher eine visit(RocketShip rocketShip) -Methode hinzufügen.

Sie können dieses Problem abmildern, indem Sie ein VehicleVisitorTemplate erstellen, bei dem alle Besuchsmethoden überschrieben werden. Ihre Operationen bilden die Vorlagenklasse ab und müssen nur die erforderlichen Methoden überschreiben. Wenn Sie eine neue Klassen- und Besuchsmethode hinzufügen müssen, fügen Sie sie der Schnittstelle und der Vorlagenklasse hinzu, und dann müssen alle anderen Operationen nicht aktualisiert werden, es sei denn, dies ist erforderlich.

    
David Smith 18.12.2009 05:59
quelle
0

Ich sehe nicht, welche Sprache Sie verwenden, aber warum sollte die abstrakte Klasse die Schnittstelle nicht implementieren? Auf diese Weise ist es egal, wie viele konkrete Klassen Sie haben, solange sie alle von der abstrakten Klasse erben, die die Schnittstelle implementiert.

So sieht die Hierarchie aus, wenn Sie Java verwenden:

%Vor%

Diese würden natürlich alle in verschiedenen Dateien definiert sein.

    
ssakl 17.12.2009 18:15
quelle
0
  

Wie kann ein Manager zum Beispiel Verkehrsmanager nach einem bestimmten Gegenstand suchen, indem er die abstrakte Klasse verwendet, ohne auf Auto oder Bus zu werfen

Ich würde das so machen, dass die abstrakte Klasse eine abstrakte Methode hat, die einen ID-Wert (z. B. einen Aufzählungswert) zurückgibt, der angibt, welcher konkrete Typ das Objekt ist, und dass jede konkrete Klasse die zurückzugebende Klasse überschreibt sein ID-Wert.

Oder ich würde versuchen, die RTTI-Funktionen von C ++ oder Pythons instanceof() -Funktion zu verwenden.

Hilft das, oder beantworte ich die falsche Frage?

    
Mike DeSimone 17.12.2009 18:18
quelle
0

Das klingt wie ein Anwendungsfall für das Spezifikationsmuster.

Ссылка

Ссылка

Viel Glück!

    
Bennett Dill 17.12.2009 18:47
quelle

Tags und Links