OK, alors j'ai la situation suivante. J'ai initialement eu un code comme celui-ci:
public class MainBoard {
private IBoardType1 bt1;
private IBoardType2 bt2;
private IBoardType3 bt3;
...
private Size boardSize;
public MainBoard(Size boardSize, IBoardType1 bt1, IBoardType2 bt2, IBoardType3 bt3) {
this.bt1 = bt1;
this.bt2 = bt2;
this.bt3 = bt3;
}
}
8 Réponses :
Il est douteux de savoir si l'injection de dépendance (ou l'inversion de dépendance) devrait être appliquée dans ce cas. Il me semble que votre C'est un compromis entre la flexibilité et les tâches supplémentaires du côté de la consommation. P>
D'autre part, s'il est judicieux d'avoir le cycle de vie de Mainboard code> est de la carte code> it créé dans le premier échantillon. Si vous injectez maintenant votre conseil d'administration, cette responsabilité doit être traitée par les consommateurs Mainboard code>. P>
BOARTYPE code> S être géré Mainboard code> doit alors s'assurer que ses dépendances sont code> est égale. P>
Je fais cela de cette façon afin que je puisse facilement tester la classe. L'avoir comme dans le premier cas le rend difficile, voire impossible, à tester.
Vous pouvez toujours utiliser le deuxième constructeur, mais utiliser une surcharge de commodité ou une usine pour la production.
Vous pouvez obtenir la planche en planche de l'une des planches qui sont transmises à travers di. De cette façon, vous pouvez perdre la variable de planche-pied allommante. P>
C'est vrai, mais des erreurs étranges peuvent survenir si je ne prends pas de mesures pour vous assurer que tous les 3 planches ont la même taille.
Je dirais que le paramètre Mais dans l'ensemble, le second cas semble douteux pour moi. Je suggérerais la première approche, à moins que vous n'ayez vraiment pas besoin d'injecter différents types de planches à la carte principale. Même donc, j'envisagerais d'utiliser par exemple. une planche usine au lieu de passer 3 paramètres de la carte au constructeur, par exemple P> botsize code> est inutile dans le second cas, mais j'ajouterais une affirmation pour vous assurer que les 3 tailles de la carte sont vraiment égales. public interface IBoardBuilderFactory {
public IBoardType1 createBoardType1(Size boardSize);
public IBoardType2 createBoardType2(Size boardSize);
public IBoardType3 createBoardType3(Size boardSize);
}
HMMM injectant une usine semble être une bonne idéie. Laisse moi y réfléchir.
HMM L'usine est parfaite si les 3 tableaux ont des constructeurs égaux. S'ils ont des constructeurs différents, je suis alors tenu de devoir les transmettre au constructeur de l'usine. Il peut effectivement appliquer la cohérence des tailles sur les 3 planches, mais je reçois aussi un fouineur machin usine constructeur :(
@Devoura, pas sûr si je comprends ce que vous voulez dire ... Les types de la carte de béton, comme indiqué dans votre échantillon de code, ont des constructeurs similaires, chacun prenant un seul paramètre code> de taille code>.
Oui, désolé pour ça. Dans ce cas, oui, ce que vous avez mis est parfait. Mais je crains plus tard, ils pourraient avoir différents constructeurs chacun, tout cela!
Injecter une usine comme celle-ci signifie que la carte mère doit maintenant connaître les paramètres de construction aux différentes planches. Il serait préférable d'injecter une usine avec une planche en planche déjà définie qui renvoie simplement les valeurs (ou voir ma réponse pour une alternative).
@Ww, les usines du sens classique sont apatrides. Une usine avec l'état ressemble plus à un Builder . Pour moi, il est tout à fait raisonnable que la carte mère contrôle les paramètres de construction de ses panneaux de fronton - en fonction de sa fonctionnalité, il peut être nécessaire de connaître la taille de la carte de toute façon. Mais votre suggestion peut en effet être meilleure si la carte principale n'utilise pas la taille du conseil d'autres méthodes. Comme je l'ai noté ci-dessus, nous avons trop de petites informations pour décider.
Quel type d'info fait-il que la classe et si la taille de la carte doit être déterminée à l'extérieur, vous ne le stockez pas du tout. Peut-être que l'usine détermine la taille de la carte à utiliser lorsqu'elle est construite ailleurs. P> Quoi qu'il en soit, le point est que les modèles de conception sont là pour vous aider à accomplir des tâches de manière propre et maintenue. Ils ne sont pas des règles difficiles et rapides qui doivent être suivies p> p> booktypeex code> contient? A-t-il de sens que cet objet injecté dans votre Mainboard. CODE> L'injection de dépendance et les motifs en général n'est pas
Je le fais en raison des tests unitaires. Je dois être capable de mettre les sous-commissions à certains états afin que je puisse tester la classe de la carte mère.
Eh bien, à des fins de test, vous pourriez avoir un test de testBuilderFactory pouvant renvoyer des cartes dans différents états de la méthode Buildboard (). Peut-être que cette classe a des sous-classes, des constructeurs différents ou autre.
Vous pourriez avoir une carte de route qui crée des traits de bord, comme: P>
Notez qu'il existe des tonnes de poteaux de blog et donc des réponses sur la meilleure façon d'écrire une usine, ce qui précède est un exemple simple. em> p>
Vous pouvez ensuite appeler p>
Passer la taille de la source qui a été utilisée pour créer les planches. P> ioboardtype bt1 = boardypefactory.create (conseil en planche); code> p>
nouvelle carte mère (Boardise, BT1, .... Code> P>
Je ne vois pas ce que je gagne en le faisant de cette façon. J'ai toujours le même problème, sans garantir la cohérence des tailles du conseil d'administration lors de la transmission de la classe de la carte mère.
Où j'ai dit garantir, je voulais dire plus quelque chose comme "appliquer"
Salut. Depuis la même référence code> la variable code> a été utilisé dans le .Create () code> appel de l'usine et de la nouvelle carte mère () code> appel, vous utilisez un Taille du conseil cohérent car la même valeur est passée aux deux appels de méthode.
-Edit - supprimé la majeure partie de ma réponse parce que d'autres me battent :) p>
Une autre option - usines. Selon vos besoins, vous pourriez le trouver mieux (ou non) d'utiliser des usines pour résoudre votre problème. Il y a une bonne discussion ici sur les usines vs di. Vous pouvez même envisager de passer un factroy via DI dans votre constructeur de classe - de sorte que votre constructeur prend une taille et une classe d'usine, et se déchirera à la classe d'usine (en passant dans la taille) pour obtenir les planches. P>
On dirait que la plupart des gens m'ont frappé avec la discussion d'usine aussi;)
L'injection principale de la dépendonnée est l'isolation des modifications apportées aux objets injectés. Donc, dans votre cas, une variable apparente est la taille. Vous introduisiez les conseils d'administration dans la commission principale de sorte que la commission principale n'a plus besoin de connaître ou de s'inquiéter de la taille. En outre, à moins que votre application ne doit conserver 3 comportements distincts entre les différents types de cartes, je suggérerais d'utiliser une définition abstraite unique pour l'interface de type de carte.
public class BoardAssembler {
public static MainBoard assembleBoard(Size size) {
Size innerBoardSize = deriveSizeOfInternalBoards(size);
return new MainBoard(new BoardType1(innerBoardSize), new BoardType2(innerBoardSize), new BoardType3(innerBoardSize));
}
}
Dans le cadre de Mainboard code>, le botsize code> est efficacement une constante. Vous voulez seulement une seule valeur d'informer. Vous avez besoin d'un code comme celui-ci: IBoardType1 b1 = injectBoardType1( myScope );
IBoardType2 b2 = injectBoardType2( myScope );
IBoardType3 b3 = injectBoardType3( myScope );
return new MainBoard( scope.getBoardSize, b1, b2, b3 );
Je pense que plus d'informations pourraient être nécessaires - il est difficile de répondre à une question comme celle-ci sans plus de contexte.
Exactement! Demandez-vous: "Quel est le comportement de la carte mère?" C'est ce que vous écrivez dans le test de l'unité. La carte mère interagit probablement avec tous les tableaux de la même manière qui peuvent appeler une seule interface abstraite ou non. Vous testez l'interaction de la carte mère avec ses constituants. Ensuite, vous utilisez une usine pour créer de la carte mère et ses constituants. Enfin, vous remplacez l'appel original à la CTOR de la carte mère avec un appel à l'usine. Laver, rincer et répéter l'idée de la classe qui appelle dans la nouvelle usine.
Toutes les planches ont des comportements / méthodes différents. Ce n'est pas un cas pour le polymorphisme.
Vous ne devez pas coder pour autoriser les tests d'unités, vous devez simplement utiliser un bon cadre de test unitaire. Utilisez PowerMock ou similaire et se moquer de la "nouvelle" appels ou de définir l'état interne de l'objet après l'avoir instancié dans le cas d'essai.