Wie kann ich das besser gestalten? (Vermeidung einer switch-Anweisung mit objektorientiertem Design)

7

Ich weiß ein bisschen über Objektorientiertes Design , aber ich bin mir nicht sicher, wie ich diese Prinzipien anwenden soll in meinem Code. Hier ist, woran ich arbeite:

%Vor%

(Die meisten davon sind Objekte aus NHibernate. Ich arbeite mit einem Legacy-Datenbanksystem und teile Teile davon in eine Codebibliothek um.) Natürlich könnte ich hier etwas anders machen, so dass ich keine doppelten Funktionen benötige für verschiedene Datenbankabfragen, die die gleiche Eingabe haben. Es sollte nur anhand des Agenturobjekts bekannt sein, ob eine Oracle-Datenbank oder eine Pick-Datenbankverbindung verwendet werden soll. (Wenn Sie noch nie von einer Pick-Datenbank gehört haben, hatte ich auch keine, bis ich hier anfing zu arbeiten. Wir machen Anfragen über HTTP-Anfragen, also ist es nicht SQL.)

Soll ich eine Schnittstelle erstellen, zum Beispiel "ClientDbConnection", und dann zwei Klassen implementieren, die diese Schnittstelle implementieren, verschieben Sie den Code, um die Datenbank auf diese abzufragen und dann etwas wie "agency.clientDb.Query (queryCitation)" zu ersetzen diese ganze Funktion? Ich denke, ich denke hier laut nach, aber jeder Beitrag dazu wäre willkommen.

    
Chris 25.04.2011, 13:43
quelle

6 Antworten

11

Ist Agency eine Klasse, die Sie kontrollieren? Wenn ja, mache so etwas:

%Vor%

In Ihrer Agenturklasse könnten Sie

haben %Vor%

Dann haben Sie eine SqlDb Klasse wie:

%Vor%

Dann dieser Code:

%Vor%

wird

%Vor%

Aufgrund der Vererbung weiß es, dass ClientDb eine Basisklasse von GenericDb hat. Es wird durch den Typ des ClientDb-Parameters wissen, ob es das SqlDb oder das PicDb oder Oracle usw. ausführen soll.

    
taylonr 25.04.2011, 13:51
quelle
5

Sie werden wahrscheinlich das Strategie-Muster hier implementieren wollen. Grundsätzlich würde jeder Ihrer möglichen "Typen" in Ihrer switch-Anweisung eine eigene Klasse werden, die dieselbe Schnittstelle implementiert.

Anwenden des Strategie-Patterns

Sie können dann eine Factory-Methode verwenden, die einen "type" -Wert als Parameter verwendet. Diese Methode würde die korrekte Klasse zurückgeben (ihr Rückgabetyp ist die oben erwähnte Schnittstelle).

    
ventaur 25.04.2011 13:50
quelle
3

Ich würde umgestalten, um eine Schnittstelle zu nutzen. Ich würde es wahrscheinlich so machen:

%Vor%

Sie könnten dann die Agency-Klasse ändern, um eine Instanz eines IQuery -Objekts anstatt (oder zusätzlich dazu) des ClientDb -Objekts zu speichern:

%Vor%

Und dann könnten Sie in Ihrem Initialisierungscode (in dem Sie normalerweise die ClientDb -Eigenschaft festlegen würden) die Instanz auf die entsprechende IQuery -Implementierung setzen:

%Vor%     
Justin Niessner 25.04.2011 13:46
quelle
2

ADO.NET hat eine Reihe von generischen Klassen: DbCommand, DbConnection, etc ..., die auch einen weiteren Satz von generischen Interfaces implementieren: IDbCommand, IDbConnection, etc ...

Du könntest sie also benutzen, aber am Ende wird es vielleicht ziemlich kompliziert. Der Vorteil Ihrer Lösung ist, dass sie gut lesbar ist. Und vielleicht hat die Auswahldatenbank keinen ADO.NET Provider ...

PS: Ich würde den Type-Eigenschaftstyp jedoch ersetzen und stattdessen eine enum verwenden.

    
Simon Mourier 25.04.2011 13:50
quelle
2

Um weniger Code zu schreiben, aber die Lesbarkeit zu verbessern, können Sie die Ebene des deklarativen Codes in ein Wörterbuch mit Delegierten für jede Datenbank umwandeln. Das kann leicht erweitert werden und ist sehr gut lesbar. Mit dieser eher funktionalen Herangehensweise erhalten Sie etwas wie

%Vor%     
Alois Kraus 25.04.2011 18:58
quelle
0

Es gibt zwei OOP-Lösungen Polymorphismus und Besuchermuster .

    
Stas Kurilin 25.04.2011 13:51
quelle

Tags und Links