Qu'est-ce que L'AOP, L'Injection de dépendances et L'Inversion de contrôle en anglais Simple
6 réponses
je comprends votre confusion et il m'a fallu un certain temps pour comprendre comment ces concepts étaient reliés ensemble. Voici donc mon explication (en quelque sorte personnelle) de tout cela:
1. Inversion de la commande
Inversion de la commande est un principe de conception plutôt générique qui se réfère au découplage de la spécification d'un comportement à partir du moment où il est effectivement exécuté. Comparer par exemple,
myDependency.doThis();
avec
myDependency.onEventX += doThis();
dans ce dernier, il y a sans invocation directe qui est plus souple. Dans sa forme générale, l'inversion de contrôle se rapporte à la modèle observateur , événements , ou rappels .
2. Inversion de dépendance
inversion de dépendance est un autre principe de conception. En gros, il est dit que l'abstraction de niveau supérieur ne devrait pas dépendre directement des abstractions de niveau inférieur; il en résulte en effet un design où l'abstraction de niveau supérieur ne peut pas être réutilisée sans les abstractions de niveau inférieur.
class MyHighLevelClass {
MyLowLevelClass dep = new MyLowLeverClass();
}
class App {
void main() { new HighLevelClass().doStuff(); }
}
ici, MyHighLevelClass
ne peut pas être compilé sans accès à MyLowLevelClass
. Pour briser ce couplage, nous avons besoin de abstract la classe de bas niveau avec une interface, et supprimer le instanciation directe.
class MyLowLevelClass implements MyUsefulAbstraction { ... }
class MyHighLevelClass {
MyUsefulAbstraction dep;
MyHighLevelClass( MyUsefulAbstraction dep ) {
this.dep = dep;
}
}
class App {
void main() { new HighLevelClass( new LowLevelClass() ).doStuff(); }
}
notez que vous n'avez pas besoin de quelque chose de spécial comme un conteneur pour forcer l'inversion de dépendance, ce qui est un principe. Une bonne lecture est le principe de L'Inversion de dépendance par L'oncle Bob.
3. Injection de dépendance
vient maintenant l'injection de dépendance. Pour moi dependency injection = IoC + dependency inversion
:
- les dépendances sont fourni extérieurement afin que nous appliquions le principe de l'inversion de dépendance
- le conteneur définit les dépendances (pas nous) donc nous parlons d'inversion de contrôle
dans l'exemple que j'ai fourni ci-dessus, l'injection de dépendances peut être faite si un conteneur est utilisé pour instancier des objets et automatiquement injecter la dépendance dans le constructeur (nous parlons alors fréquemment de conteneur DI):
class App {
void main() { DI.getHighLevelObject().doStuff(); }
}
noter qu'il existe diverses formes d'injections . Notez aussi que dans cette perspective, setter injection peut être considéré comme une forme de callback -- le conteneur DI crée l'objet puis rappelle le setter. Le flux de contrôle est effectivement inversé.
4. AOP
à proprement parler, AOP n'a pas grand chose à voir avec les 3 points précédents. Le papier fondateur sur AOP est très générique et présente l'idée de tisser diverses sources ensemble (peut-être exprimée avec différentes langues) pour produire un logiciel de travail.
Je ne vais pas développer plus sur AOP. Ce qui est important ici, c'est que l'injection de dépendance et L'AOP jouent efficacement bien ensemble car cela rend le tissage très facile. Si un conteneur du CIO et une injection de dépendance sont utilisés pour effacer l'instanciation des objets, le conteneur du CIO peut facilement être utilisé pour tisser les aspects avant d'injecter les dépendances. Cela nécessiterait par ailleurs une compilation spéciale ou une ClassLoader
spéciale .
Espérons que cette aide.
l'injection de Dépendance est très bien expliqué dans Comment expliquer l'injection de dépendance pour un enfant de 5 ans? :
quand vous allez et sortez des choses de la réfrigérateur pour vous-même, vous pouvez causer des problèmes. Vous pourriez quitter le porte ouverte, vous pourriez obtenir quelque chose La maman ou le Papa ne veut pas que vous avoir. Vous pourriez même être à la recherche quelque chose que nous n'avons même pas ou qui a expiré.
Ce que vous devriez faire est d'énoncer un besoin, "j'ai besoin de quelque chose à boire avec déjeuner," et ensuite nous nous assurerons que vous avoir quelque chose quand vous vous asseyez pour manger.
AOP - Aspect de la Programmation Orientée - signifie que la source que vous écrivez est modifié avec un autre code, basé sur des règles se trouve AILLEURS. Cela signifie que vous pouvez par exemple dire: "comme la première ligne de chaque méthode, je veux un 'journal.debug("saisie méthode() ")' dans une centrale place et chaque méthode que vous compilez avec cette règle en place aura alors cette ligne incluse. L '"aspect" est le nom de la recherche sur le code d'une autre manière que simplement de la première ligne de la source à la dernière.
Inversion de contrôle signifie essentiellement que vous n'avez pas un morceau de code central contrôlant tout (comme un interrupteur géant dans main ()) mais ont beaucoup de morceaux de code qui "d'une façon ou d'une autre" obtenir appelé. Le sujet est discuté sur Wikipedia: http://en.wikipedia.org/wiki/Inversion_of_control
ces trois concepts sont tous différents, mais ils fonctionnent tous bien ensemble, et donc les applications de printemps font souvent usage de tout à la fois. Je vais vous donner un exemple.
disons que nous avons une application web qui peut faire beaucoup de choses différentes. Nous pourrions construire cette application de plusieurs façons, mais une façon est de créer une classe qui est chargée de faire chacune de ces choses. Nous devons invoquer et créer ces classes à partir de quelque part. Une option est d'avoir un grand classe principale qui crée un de chacun de ces services, ouvre une socket, et passe des appels à ces services comme ils viennent. Malheureusement, nous sommes allés nous créer une classe de Dieu, qui a beaucoup trop de logique et sait beaucoup trop sur la façon dont tout dans notre programme fonctionne. Si nous changeons quelque chose à propos de notre programme, nous allons probablement avoir besoin de modifier cette classe.
Aussi, c'est difficile à tester. Nous ne pouvons tester aucune classe isolément si elle tourne autour instanciation et invocation directe des autres classes. Les tests unitaires deviennent beaucoup plus difficiles à écrire.
une façon de contourner cela est d'utiliser l'inversion de commande. On dit "OK, ce sont des cours de service. Qui instatiates? Pas moi."Habituellement, chacun définit une interface, comme LoginService ou BillingService. Il peut y avoir plus d'une implémentation de cette interface, mais votre application s'en fiche. Il sait juste qu'il peut demander un certain type d'un service ou d'un service avec un certain nom, et il obtiendra quelque chose de beau retour.
L'injection de dépendancenous permet de raccorder tous nos petits morceaux ensemble. Les Classes ont des champs accessibles, des arguments de constructeur ou des méthodes de setter qui sont des références aux autres composants auxquels elles devront accéder. Cela rend les tests unitaires beaucoup plus faciles. Vous pouvez créer l'objet sous test, jeter une maquette ou talon de la dépendance, et alors vérifier que l'objet s'est comporté correctement dans l'isolement.
maintenant, notre véritable application est un mélange complexe de pièces qui ont toutes besoin d'être câblées ensemble. Il y a plusieurs façons d'y parvenir, y compris en permettant à l'application de faire des suppositions ("cette classe veut un UserService, il y a exactement une autre classe dont je suis responsable qui implémente UserService") ou en expliquant soigneusement comment ils se connectent en XML ou en Java. Spring, à sa base, est un service qui prend soin de câblage de ces classes ensemble.
maintenant nous arrivons à AOP. Disons que nous avons tous ces cours qui sont connectés les uns aux autres de manière élaborée. Il y a certaines préoccupations transversales que nous pourrions vouloir décrire de façon très générale. Par exemple, vous aimeriez peut-être lancer une transaction de base de données chaque fois qu'un service est invoqué, et engager cette transaction tant que le service ne fait pas d'exception. Il s'avère que le ressort est dans une position unique pour effectuer une telle tâche. Le printemps peut créer un proxy des classes à la volée qui implémentent n'importe quelle interface dont vos classes ont besoin, et qui peuvent envelopper votre classe dans son proxy. Maintenant, la recherche des causes et l'injection de dépendances ne sont certainement pas nécessaires pour faire de la programmation orientée vers l'aspect, mais c'est un moyen extrêmement pratique pour l'accomplir.
laissez-moi vous dire un mot sur AOP, j'espère qu'il sera plus simple à comprendre. Le principe de base de L'AOP est de trouver des tâches/aspects communs beaucoup d'endroits dans le code et n'appartiennent pas à l'affaire de concerete du code. Exemple Ecrivez pour ouvrir une session sur chaque entrée de n'importe quelle fonction, ou quand un objet est créé wrapp il, ou envoyez un email à l'administrateur en appelant à la fonction spécifique. Donc, au lieu des programmeurs s'occuperont de cet aspect non-business nous le prenons à partir d'eux et nous gérons ces aspects au-delà de la scène. Que toutes les règles de base de l'AOP sur 1 jambe....
Une simple comparaison de Printemps dans l'Action:
alors que DI vous aide à découpler votre application objets les uns des autres, AOP vous aide à découpler les préoccupations transversales de la les objets qu'ils touchent.
La différence entre l'Injection de Dépendance et d'Inversion de Contrôle est très bien expliqué dans
http://martinfowler.com/articles/dipInTheWild.html
("vous voulez dire L'Inversion de dépendance, N'est-ce pas?"section)
le résumé:
DI est sur la façon dont un objet acquiert une dépendance. Quand une dépendance est fourni à l'extérieur, puis le système utilise DI.
le CIO se demande qui est à l'origine de l'appel. Si votre code lance un appel, ce N'est pas CIO, si le conteneur / système / bibliothèque rappelle dans le code que vous l'avez fourni, C'est le CIO.