2011-05-23 3 views
23

Voici un exemple imaginaire générique composé pour ce poste. Tenez compte 6 classesDependency Hell - comment passer les dépendances aux objets profondément imbriqués?

TableFactory, TableData, TableCRUD, TableSchema, DBConnect, Logger. 

TableFactory est la classe externe, disons que détient un objet TableData pour une table DB.

Dans ce TableFactory, il n'y a pas d'appels à TableSchema ou DBConnect ou logger. Je vise un exemple d'objets intérieurs qui ne sont pas nécessaires dans la portée extérieure.

TableData est un interne récupère et fonctionne sur les données, de sorte qu'il a besoin TableCrud, DBConnect et Logger.

TableCrud contient TableSchema et nécessite DBConnect et Logger.

DbConnect Pour rendre les choses amusantes, il faut un enregistreur. Mon exemple est maintenant 3 profondeurs. Ma question est assez simple, si vous avez un objet 3 (ou plus) dans les étendues qui ne sont pas appelées par des objets sur la portée externe, comment peut-on envoyer ces objets de la portée externe à interne sans rompre la ségrégation de l'interface Principe -> TableFactory ne devrait pas avoir à gérer DBConnect ou Logger requis par les objets internes. Si l'on respecte les principes de base de la POO et que l'on vise une facilité de testabilité -> on aurait besoin d'objets extérieurs nécessitant l'injection des 5 objets, puis de méthodes getter qui passeraient les objets nécessaires plus haut dans la chaîne. Et les objets à portée interne nécessiteraient à leur tour l'injection des dépendances de leurs objets intérieurs profonds à trois dimensions, avec des getters pour ceux-là aussi. Cela fait pour les objets à portée externe nécessitant de nombreuses dépendances, et les getters juste pour les transmettre.

Existe-t-il une alternative à cette méthodologie de passage d'objet, quelque chose que j'ai manqué en cours de route? Partagez s'il vous plait! Tous les liens/commentaires appréciés.

Répondre

45

C'est une idée fausse très répandue que les dépendances doivent être passées à travers le graphe d'objets. Pour résumer l'exemple Miško Hevery donne à Clean Code: Don't look for things, une maison qui a besoin d'une porte, n'a pas besoin de savoir sur le verrou de la porte:

class HouseBuilder 
{ 
    public function buildHouse() 
    { 
     $lock = new Lock; 
     $door = new Door($lock); 
     $house = new House($door); 

     return $house; 
    } 
} 

Comme vous pouvez le voir, House est complètement inconscient du fait que la porte il nécessite un verrou. C'est la responsabilité de HouseBuilder de créer toutes les dépendances requises et de les empiler ensemble selon les besoins. À l'envers.

Par conséquent, dans votre scénario, vous devez identifier quels objets doivent fonctionner sur quelles dépendances (cf. Law of Demeter). Votre Builder doit ensuite créer tous les collaborateurs et s'assurer que les dépendances sont injectées dans les objets appropriés.

Voir aussi How to Think About the “new” Operator with Respect to Unit Testing

+6

+1 aime la façon dont cela est mis, agréable et propre! – Christian

+1

Gordon -> Vous bercez! ;) Merci copain et si vous venez jamais à Montréal, je vous dois une bière pour toutes les fois que vous me avez clued! Vous n'avez pas besoin du karma de toute façon. – stefgosselin

+0

@stef vous êtes les bienvenus. Je ne sais pas si j'irai à Confoo l'année prochaine, mais si je le fais, je serai heureux de prendre une bière avec vous;) – Gordon

1

Si vous trébuchent sur la même question vérifier l'article de Hervey qui frappe les taureaux oeil

http://misko.hevery.com/2008/10/21/dependency-injection-myth-reference-passing/

Dans le cas où l'article disparaît à l'avenir est ici l'extrait

« Chaque objet sait simplement sur les objets qu'il interagit directement avec. il n'y a pas passage d'objets de référence juste pour les obtenir dans le bon endroit où ils sont n cédé. "

donc ce que l'on besoin de faire est au lieu de créer un graphique d'objets imbriquées profond avec le passage des dépendances vient de haut en bas, aller horizontale et gérer les dépendances ailleurs.

Questions connexes