2016-07-05 10 views
1

Ich habe drei Fragen über die Inversion der Kontrolle.Inversion der Kontrolle und interne Klassen

Ich baue ein Schachprogramm mit C# und ich habe den Code in eine Reihe von Klassenbibliotheken aufgeteilt. Die Idee besteht darin, die gesamte Logik über Platinenpositionen und Stückbewegung an einem Ort zu kapseln, die gesamte Logik über das Abrufen von Spieldaten in einem anderen und alle Daten über das Anzeigen eines Schachbretts in einem dritten (die Benutzeroberfläche).

Ich habe eine Bibliothek, die die "Business-Schicht" der Anwendung ist, mit Schnittstellen & Klassen für das Spiel, die Spieler, das Brett, die Quadrate auf dem Brett und Stücke. Für jedes dieser Objekte gibt es eine öffentliche Schnittstelle. Die Klassen, die diese Schnittstellen implementieren, sind jedoch intern. Es scheint mir, dass dieser Ansatz verhindern wird, dass Code außerhalb der Bibliothek instanziiert wird oder gar eines der Interna kennt, und dies ist der richtige Weg. Clients sollten nur die Methoden & Eigenschaften der Schnittstellen verwenden.

Erste Frage: Ist dieser Ansatz in Ordnung oder verstößt er irgendwie gegen den DI-Principal?

Ich habe gekämpft mit, ob ich die IPiece Schnittstelle mit dem IoC oder sogar einer der Schnittstellen außer IGame registrieren sollte. Der Grund dafür ist, dass Clients nur Objekte erstellen können, die IGame implementieren, und alle Objekte, die die anderen Schnittstellen implementieren, werden mitgeliefert. (Ich meine, du erschaffst ein neues Spiel, du bekommst ein Brett mit allen 64 Quadraten und den 32 Stück darauf fertig gemacht. Oder du holst ein gespeichertes Spiel zurück & das Brett & die Quadrate werden erstellt & die Teile werden darauf in ihren gelegt vorherige Standorte, keine Notwendigkeit für den Kunden, dies zu tun).

Zweite Frage: Ist das OK oder verstößt es gegen das Abhängigkeits-Injektionsprinzip?

Die Schnittstelle IPiece definiert alle Funktionen, die für ein Stück benötigt werden, unabhängig davon, um welche Art von Stück es sich handelt. Es gibt sogar eine Eigenschaft, die von der Benutzeroberfläche verwendet werden kann, um die Ressourcen-ID für das Bild zu erstellen, das für die Anzeige des Stücks verwendet wird. Daher muss der Client nicht wissen, was die Klasse eines Stücks ist.

Das Problem ist, dass es eine abstrakte Basisklasse, die die IPiece Schnittstelle implementiert Piece und 6 Kind-Klassen genannt, die von ihm abstammen (Bishop, Knight, King, Queen, Rook und Pawn). Ich weiß nicht, wie man alle diese Klassen gegen die Schnittstelle IPiece registriert, oder sogar wenn ich sollte.

Ich möchte nicht, dass Kunden sich darum kümmern müssen, mit welcher Art von Werkstück sie arbeiten, oder um sie zu erstellen. Wenn ein neues Spiel gestartet wird, werden die Teile & auf dem Board automatisch durch eine Methode auf der IGame Schnittstelle erstellt. Wenn Sie ein gespeichertes Spiel laden, werden die Teile auf einer anderen Methode in der gleichen Oberfläche erstellt und auf die Karte verschoben, ohne dass der Client etwas anderes tun muss, als die Daten abzurufen und an die Methode zu übergeben. Dies bedeutet, dass die internen Klassen in der Schach-Engine-Bibliothek ohne die Verwendung des IoC instanziiert werden.

Die Idee ist der Client nur alle Teile & iteriert sie auf der Bildschirmtafel an der richtigen Stelle, ohne dass es die Klasse des Objekts zu kennen. Alle Informationen, die der Client benötigt, werden in Eigenschaften bereitgestellt, die durch die Schnittstelle IPiece definiert sind.

Dritte Frage: Ist das OK oder sollte ich IBishop definieren usw. & die Klassen zu den Schnittstellen IoC registrieren, obwohl die IoC-Zuordnung nie außerhalb der Klassenbibliothek verwendet werden?

+1

Ich denke, Sie müssen in Fabriken zu sehen, dann können Sie die einzelnen Stücke Referenzen, wo sie gehören. Ich habe eine [Antwort hier] (http://stackoverflow.com/questions/38193830/dependency-injection-and-project-references/38195003#38195003) mit ein paar Beispielen, wie man mit Hilfe von Fabriken, die Sie geben könnte, zu implementieren Idee. Diese Frage ist auch mit anderen verwandten Informationen zum Thema verknüpft. – Tone

Antwort

1
  1. Theoretisch sollten Sie in Ordnung sein. Berücksichtigt man jedoch, dass der größte Vorteil von IoC/DI darin besteht, dass das Testen viel einfacher wird, benötigen Sie wahrscheinlich einen Hinweis auf die Implementierung, wenn Sie es testen. Davon abgesehen, können Sie entweder auf die InternalsVisibleToAttribute zurückgreifen, oder Sie müssen möglicherweise nicht, wenn Sie keine Unit-Tests durchführen (obwohl ich es sehr empfehlen würde);
  2. Ihre Argumentation klingt auch hier gut. Sie können dies auf eine minimalistische Art und Weise tun: Beginnen Sie damit, dass Sie nichts registrieren, den Code ausführen und die Typen so lange registrieren, wie sie benötigt werden, und nicht früher;
  3. Gleich wie zuvor, gehen Sie auf eine Need-to-Know-Basis; oder gehen Sie mit dem @ Tone-Vorschlag, wenn es in Ihrem Fall geeignet ist - haben Sie eine IPieceFactory mit einer Implementierung, um die gesamte Erstellungslogik beizubehalten.
+0

Das macht Sinn. Ich muss Komponententests für jede der Methoden in jeder der Klassen erstellen. Ich hatte nicht über die Auswirkungen der Interna auf Tests nachgedacht. Ich werde darüber nachdenken. –

Verwandte Themen