2009-05-25 3 views
0

Nehmen wir an, ich habe eine Schnittstelle namens "Controller". Mehrere Klassen implementieren diese Schnittstelle und ich kenne diese Klassen nicht (z. B. befinden sich die Klassennamen in einer XML-Datei). Damit diese Controller-implementierenden Klassen funktionieren, müssen sie einige Referenzen auf andere Objekte (möglicherweise Datenobjekte) erhalten. Und das ist meine Frage, nämlich was ist der beste Weg, um solche Objekte (die Controller-Einsen) zu initialisieren?Initialisieren eines Objekts mit Referenzen ohne Zugriff auf einen nicht standardmäßigen Konstruktor

Ich dachte an mehrere Lösungen, aber ich bin nicht wirklich sicher, was ist der beste Ansatz hier.

Zuerst: Wenn ich das Objekt vom Klassennamen instanziiere, könnte ich nach dem "speziellen" Konstruktor (über Reflektion) suchen, der die Objektreferenzen hat, die das Controller-Objekt benötigt. Aber von dem, was ich in anderen Fragen gelesen habe, ist dies weniger wahrscheinlich eine gute Lösung, weil ich einen speziellen Konstruktor zwingen würde, in der Klasse zu existieren. Und manchmal lese ich, dass Reflexion im Allgemeinen böse ist und besser vermieden wird.

Sekunde: Ich füge eine spezielle init (a, b, c) -Methode zur Controller-Schnittstelle hinzu, die direkt nach der Erstellung des Objekts aufgerufen werden müsste. Dies würde eine Folge von Aufrufen (zuerst init (..), dann Ruhe) auf das Objekt zwingen, um es zum Laufen zu bringen, was wahrscheinlich auch schlecht ist. Btw, sind init() - Methoden generell eine schlechte Sache in Schnittstellen?

Dritter: Nach der Lektüre this Kommentar ich zu folgendem gedacht: Statt die Klassennamen der Klasse mit der Steuerung-Schnittstelle implementiert (in der XML-Datei) Ich habe den Klassennamen eine Fabrik, die zu der gehört konkrete Controller-Klasse. Und diese Fabrik würde eine Schnittstelle mit der Methode createController (a, b, c) implementieren und die Fabrik würde dann wissen, welche Klasse sie instanziieren müsste und welcher Konstruktor aufgerufen werden müsste, um die anderen Referenzen (wie Datenobjekte) zu übertragen. Nachteil wäre die zusätzliche Klasse, nur um die Controller-Klasse instanziieren und vielleicht ein wenig Overhead im Allgemeinen.

Was denken Sie, ist der beste Weg, dies zu tun? Oder können Sie an etwas anderes denken, das besser ist als diese drei Wege?

Danke!

+0

Ich würde damit anfangen, darüber nachzudenken, ob diese XML-Datei wirklich das ist, was Sie tun möchten. –

+0

Hm, irgendwie muss ich herausfinden, welche Controller-Klassen ich habe.Aber du könntest recht haben, ich habe versucht, eine Art Modulsystem zu schaffen, und ich bin immer noch ein Lernschüler, also könnte es für die Welt nicht vorzeigbar sein: P – letmaik

Antwort

4

Von den Ansätzen, die Sie erwähnen, würde ich die zweite (Fabrik-basierte) wählen. Da jedoch, was Sie tun ist eine Form der Abhängigkeitsinjektion, auch Guice, http://code.google.com/p/google-guice/ betrachten - kann es Ihnen ermöglichen, viel von dieser Arbeit zu automatisieren.

+0

+1 für Guice-ähnliche Dinge. Die zweite Option ist eine zweiphasige Konstruktion. Hast du die dritte Option gemeint? –

+0

Danke! Ich habe schon vor einiger Zeit ein bisschen in Guice geschaut, aber ich habe bis jetzt nicht wirklich gemerkt, dass es das ist, was ich bereits mache - nur manuell. Das Problem ist, dass dies für ein bereits gewachsenes Universitätsprojekt ist. Ich würde es gerne benutzen, aber ich denke, das wäre nicht leicht möglich. Ich denke, ich werde bei der Fabriklösung bleiben. – letmaik

+0

Nur ein kleiner Hinweis - ich benutze Guice in einem neuen Projekt und ich liebe es. Also danke für die Empfehlung! – letmaik

0

In etwas Ähnlichem in einer anderen Sprache, bin ich dafür bekannt, die init() Lösung zu verwenden.

2

Was Sie zu tun versuchen ist sehr ähnlich wie bei Spring. In Ihrer XML-Datei hat Ihr Controller-Knoten untergeordnete Knoten zum Festlegen von festzulegenden Eigenschaften. Ihr Controller wird durch Aufruf des Standardkonstruktors instatiert. Dann werden die Eigenschaften durch Reflexion festgelegt.

+0

+1 für den Frühling. Einige Beispiele für Spring-Konfigurationen: http://static.springframework.org/spring/docs/2.0.x/reference/beans.html#beans-some-examples –

+0

+1 Für den Frühling. Es scheint, dass Sie versuchen, eine eigene Abhängigkeitsinjektion zu schreiben. Es gibt viele (Spring, Guice, Seam, um nur ein paar zu nennen), also ist das ziemlich überflüssig. –

+0

Sieht auch ziemlich interessant aus, ich werde definitiv ein solches Framework das nächste Mal verwenden, aber für den Moment wäre es zu viel Arbeit, um eines davon zu integrieren, wie ich es im Kommentar zu Guice erklärt habe. – letmaik

0

Eine weitere Option könnte die Verwendung der Unsafe.allocateInstance (Class) sein, um Instanzen ohne Aufruf eines Konstruktors zu erstellen. Sie können die Felder mithilfe von Reflexionen festlegen.

Dies setzt voraus, dass Ihre Konstruktoren keine Nebenwirkungen haben.

+0

Hm scheint ein bisschen hacky, mit dem würde ich bestimmte Feldnamen erzwingen oder diese in die XML auch setzen. – letmaik

Verwandte Themen