Die Verwendung eines IOC-Containers wird die Geschwindigkeit Ihrer Anwendung verringern, da die meisten von ihnen Reflektion unter der Haube verwenden. Sie können auch Ihren Code schwieriger verständlich machen(?). Auf der positiven Seite helfen sie Ihnen, locker gekoppelte Anwendungen zu erstellen und erleichtern das Unit-Testing. Gibt es weitere Vor- und Nachteile für die Verwendung/Nichtverwendung eines IOC-Containers?
Antworten
Zu viele Anzeigen?Wenn Sie einen IOC-Container auf einfache Weise verwenden, wird Reflexion nur beim Start verwendet - die Anwendung ist verkabelt, um zu starten, und dann läuft sie normal weiter ohne Eingriff des Containers. Natürlich, wenn Sie den IOC verwenden, um Abhängigkeiten aufzulösen, nachdem Sie mit der Ausführung begonnen haben, kann das etwas anders sein - obwohl ich immer noch erwarten würde, dass es träge aufgelöst und zwischengespeichert wird, es sei denn, Sie haben es konfiguriert, um jedes Mal neue Instanzen zu erstellen.
Was die Verständlichkeit des Codes betrifft - ganz im Gegenteil! Mit den explizit angegebenen Abhängigkeiten ist es viel einfacher, jedes einzelne Komponente zu verstehen, und die Konfigurationsdatei(en) zeigen deutlich, wie die gesamte Anwendung zusammenhängt.
Nun, ich denke, ein Nachteil, den ich erlebt habe, ist, dass einige Entwickler scheinbar nicht in der Lage sind, IoC zu begreifen. Wir hatten ein paar Leute, die dagegen waren, nur weil sie es nicht verstanden haben. (Nicht zu sagen, dass das ein schlechter Grund ist, gegen etwas zu sein, keineswegs.)
Es fügt eine gewisse Abstraktion hinzu, die es immer wieder schafft, jemanden zu verwirren, aber ich würde sagen, dass die Vorteile in den meisten Fällen die Nachteile bei weitem überwiegen.
Ich denke, es ist fair zu sagen, dass wenn Sie ein Expertenverständnis dafür haben, wie man IOC verwendet und sowieso dazu neigen, guten Code zu schreiben, dann wird das IOC Ihren Code auf allen, außer den kleinsten Systemen, leichter verständlich machen.
Wenn Sie jedoch an einem Ort arbeiten, an dem die meisten Klassen/Methoden sehr groß sind und das Konzept des Refactorings noch nicht Fuß gefasst hat, dann wird der Versuch, ein IOC zu verwenden, wahrscheinlich die Software nur schwerer verständlich machen. Das IOC muss auch von allen gelernt werden, die an dem Projekt arbeiten, also kann das eine Überlegung sein.
Ich sehe das IOC als das Sahnehäubchen; Ich mag das Sahnehäubchen, aber nur auf einem schönen Kuchen. Wenn der Kuchen nicht von Anfang an schön ist, kümmern Sie sich zuerst um den Kuchen.
Was die Leistungsüberlastung bei der Verwendung von IOC betrifft, sehe ich dies in den meisten Fällen nicht als Problem. Der Overhead muss nicht groß sein, und angesichts der Geschwindigkeit der heutigen CPU wird der Großteil Ihrer Laufzeit wahrscheinlich sowieso auf den Datenzugriff entfallen. Wenn ein IOC sich als zu langsam für einen bestimmten Teil des Codes herausstellen würde, würde ich in Betracht ziehen, etwas Caching des zurückgegebenen Objekts hinzuzufügen oder das IOC nur aus diesem Teil des Codes zu entfernen.
Ich glaube, die Annahme über die reduzierte Ausführungsgeschwindigkeit ist in etwa derselbe Argumenttyp wie "C ist schneller als C#/Java". Während diese Aussage vielleicht für bestimmte Operationen und/oder strukturell einfache Aufgaben zutreffen mag, gilt dies nicht, sobald die Komplexität steigt.
Die Art und Weise, wie DI-Frameworks es dir ermöglichen, dich auf die Objekterstellung und -abhängigkeiten zu konzentrieren, schafft effizientere Systeme, wenn der Codeumfang zunimmt. Bei großen Anwendungen bin ich nahezu sicher, dass Code, der auf DI-Frameworks basiert, jede alternative Lösung übertrifft. Es gibt einfach so wenig Redundanz zur Laufzeit, dass es schwer ist, effizienter zu sein! Der Großteil des zusätzlichen Overheads tritt auch nur beim ersten Laden auf.
Fortgeschrittene DI-Container ermöglichen es auch, "Scope"-Magie durchzuführen, von der du ohne den Container nur träumen könntest. Mit Hilfe von Scope-Proxies kann Spring folgendes tun:
A Singleton
|
B Singleton
|
C Prototyp (pro-Aufruf)
|
D Singleton
|
E Session-Scope (Webanwendung)
|
F Singleton
Effektiv kannst du zehn Schichten von Singleton-Objekten haben und plötzlich erscheint etwas mit Sitzungsumfang.
Dinge wie Sicherheit können in völlig anderer Weise injiziert werden als du es sonst tun würdest. Oft besteht ein klassisches Paradoxon: Oft muss die GUI-Ebene detailierte Kenntnisse über die Sicherheitsberechtigungen haben. Häufig benötigt die Services-Ebene dies auch, jedoch oft auf einer anderen Detailebene (normalerweise weniger detailliert als die GUI). Der klassische Ansatz wäre, es als Parameter herumzureichen, es auf einem Threadlocal abzulegen oder einen Service zu fragen. Mit Spring kannst du es einfach dort injizieren, wo du es brauchst und sonst muss es niemand wissen.
Dies verändert tatsächlich die Anwendungsentwicklung als Ganzes. Ich hatte große Schwierigkeiten, mich daran anzupassen, aber nach diesem Schmerz sehe ich, dass es wirklich viel näher an dem ist, wie es sein sollte (im Gegensatz dazu, wie wir es gelernt haben).
Also denke ich, dass DI-Frameworks das Potenzial haben, die Art und Weise, wie du Programme erstellst, zu verändern, mit weitreichenderen Auswirkungen als nur DI. Es ist nicht nur eine glorifizierte Art, new aufzurufen.
Ich stimme allen bisherigen Antworten zu.
Was ich hinzufügen möchte, ist, dass es ein wenig Overhead schafft, weshalb es für kleine Anwendungen nicht wirklich geeignet ist.
Mittelgroße und größere Anwendungen profitieren am meisten von der Verwendung von IoC.
Sie können auch diese Frage für weitere Informationen zu Vor- und Nachteilen überprüfen: Castle Windsor Gibt es Nachteile?
- See previous answers
- Weitere Antworten anzeigen