Angenommen, wir haben 1001 Clients, die ihre Abhängigkeiten direkt aufbauen, anstatt Injektionen zu akzeptieren. Das Refactoring des 1001 ist laut unserem Chef keine Option. Wir haben nicht einmal Zugriff auf ihre Quelle, nur auf die Klassendateien.
Wir sollen das System, das diese 1001 Clients durchlaufen, "modernisieren". Wir können alles umgestalten, was uns gefällt. Die Abhängigkeiten sind Teil dieses Systems. Und einige dieser Abhängigkeiten sollen sich ändern, um eine neue Implementierung zu erhalten.
Wir möchten die Möglichkeit haben, verschiedene Implementierungen von Abhängigkeiten zu konfigurieren, um diese Vielzahl von Clients zu befriedigen. Leider scheint DI keine Option zu sein, da die Kunden keine Injektionen mit Konstruktoren oder Setzern akzeptieren.
Die Optionen:
1) Überarbeiten Sie die Implementierung des Dienstes, den die Clients verwenden, so, dass er das tut, was die Clients jetzt benötigen. Bang wir sind fertig. Nicht flexibel Nicht komplex
2) Umgestalten Sie die Implementierung so, dass sie ihre Arbeit an eine weitere Abhängigkeit delegiert, die sie über eine Fabrik erwirbt. Jetzt können wir steuern, welche Implementierung sie alle verwenden, indem wir die Fabrik umgestalten.
3) Umgestalten Sie die Implementierung so, dass sie ihre Arbeit an eine weitere Abhängigkeit delegiert, die sie über einen Service-Locator erhält. Jetzt können wir steuern, welche Implementierung sie alle verwenden, indem wir den Service-Locator konfigurieren, der möglicherweise nur hashmap
aus Zeichenfolgen für Objekte besteht, für die ein wenig Casting ausgeführt wird.
4) Daran habe ich noch gar nicht gedacht.
Das Ziel:
Minimieren Sie den Designschaden, der durch das Ziehen des alten, schlecht gestalteten Client-Codes in die Zukunft verursacht wird, ohne unnötige Komplexität hinzuzufügen.
Kunden sollten die Implementierung ihrer Abhängigkeiten nicht kennen oder kontrollieren, aber sie bestehen darauf, sie mit zu erstellen new
. Wir können nicht kontrollieren, new
aber wir kontrollieren die Klasse, die sie bauen.
Meine Frage:
Was habe ich nicht berücksichtigt?
Benötigen Sie wirklich eine Konfigurationsmöglichkeit zwischen verschiedenen Implementierungen? Für welchen Zweck?
Beweglichkeit. Viele Unbekannte. Management will Veränderungspotenzial. Nur die Abhängigkeit von der Außenwelt verlieren. Auch testen.
Benötigen Sie eine Laufzeitmechanik oder nur eine Kompilierzeitmechanik, um zwischen verschiedenen Implementierungen zu wechseln? Warum?
Kompilierzeitmechanik ist wahrscheinlich genug. Außer zum Testen.
Welche Granularität benötigen Sie, um zwischen den Implementierungen zu wechseln? Alles auf einmal? Pro Modul (jeweils mit einer Gruppe von Klassen)? Pro Klasse?
Von den 1001 wird jeweils nur einer durch das System geführt. Ändern, was alle Clients gleichzeitig verwenden, ist wahrscheinlich in Ordnung. Eine individuelle Kontrolle der Abhängigkeiten ist jedoch wahrscheinlich wichtig.
Wer muss den Schalter steuern? Nur dein / dein Entwicklerteam? Ein Administrator? Jeder Kunde für sich? Oder die Wartungsentwickler für den Client-Code? Wie einfach / robust / kinderleicht muss die Mechanik sein?
Dev zum Testen. Administrator als externe Hardware-Abhängigkeiten ändern. Das Testen und Konfigurieren muss einfach sein.
Unser Ziel ist es zu zeigen, dass das System schnell überarbeitet und modernisiert werden kann.
tatsächlicher Anwendungsfall für den Implementierungswechsel?
Zum einen werden einige Daten von der Software bereitgestellt, bis die Hardwarelösung fertig ist.