Je suis juste en train de lire Principes agiles, modèles et pratiques en C # EM> par R. Martin et M. Martin et ils suggèrent dans leur livre, de conserver toutes vos interfaces dans un projet séparé, par exemple. interfaces em>. Par exemple, si j'ai un projet GUI EM>, contient toutes mes classes d'interface graphique personnalisées, je garderai leurs interfaces dans les interfaces / em> projet. Spécifiquement, j'ai eu une classe CustomButton dans GUI EM>, je garderais l'interface ICUSTOMBUTON dans interfaces em>. P> L'avantage est que toute classe ayant besoin d'un ICUSTOMBUTON n'a pas besoin d'une référence à gui em> elle-même, mais seulement au projet les interfaces em> le projet. P> aussi, si une classe dans le GUI EM> Changement de projet et le faire en sorte que ce soit reconstruit, seuls les projets faisant directement référence au CustomButton auraient besoin de recompilation, alors que ceux qui se réfèrent à l'ICUSTOMBUTON peuvent rester intacts. P> Je comprends ce concept, mais voir un problème: p> permet de dire que j'ai cette interface: p> Comme vous pouvez le constater, il fait référence à Animatorstrategy, qui est une classe concrète et Par conséquent, assisterait dans un autre projet, permettrons de l'appeler l'animation em>.
Maintenant, le projet d'interface doit faire référence à Animation em>. D'autre part, si Animation em> utilise une interface définie dans interfaces em>, elle doit également référence à celle-ci. P> Dépendance cyclique - "Ici, nous venons". P> La seule solution de ce problème, que je vois, est que toutes les méthodes définies dans les interfaces prennent des entrées elles-mêmes. Essayer de mettre en œuvre cela, il aura probablement probablement un effet domino toutefois et nécessitera rapidement une interface pour être mis en œuvre même pour les classes les plus élémentaires. P> Je ne sais pas si j'aimerais faire face à ces frais généraux Développement. P> Toute suggestion? P> p>
4 Réponses :
La réponse simple est animatrategy devrait également être une interface. La mise en œuvre de l'animateur est dans le projet d'animation, mais l'interface serait dans une animationInterfaces ou des interfaces (au besoin) Projet. P>
Je n'aurais pas nécessairement un seul projet d'interfaces, mais un pour chaque regroupement fonctionnel. Les clients d'animation feraient référence aux animations et les clients de l'interface graphique de l'interface graphique référendraient des guitrissements. P>
De cette façon, vous conservez vos contrats, sans mélanger aucune implémentation. P>
Pour ce que ça vaut la peine, je préfère aller dans l'autre sens avec des conventions de dénomination. Placez les interfaces dans l'animation et les implémentations dans AnimationImpl (ou similaires). De cette façon, vous référenciez le nom fonctionnel. P>
Qu'en est-il de définir une interface avec des méthodes qui prennent des types génériques? Par exemple si vous avez besoin de quelques restrictions sur où L'interface n'a aucune référence à la classe de béton T variable code>, vous pouvez faire: p>
Iotherinterface code> est également défini dans votre projet d'interfaces. Ensuite, tant que votre classe particulière hérite des deux
ithing code> et
iulterInterface code>, vous pouvez utiliser la méthode
DomyThing code> et transmettre dans une instance de votre particulier classe sans avoir une dépendance circulaire. Votre code pourrait devenir: p>
animateur code>. P> p> p>
C'est une bonne idée, mais ressemble plus à un hack pour moi. Les interfaces sont là pour épeler des contrats. Comment T semble-t-il quel type de stratégie à attendre? Si j'avais Ianimpatable, je n'aurais pas besoin de T.
méfiez-vous de toujours, toujours et jamais - surtout près de tous, aucun, ni tous. strong> p>
devriez-vous toujours em> mettre tous em> d'entre vous interfaces dans un assemblage séparé? Non - pas nécessairement. P>
Si vous mettez des interfaces que vous attendez des consommateurs externes de votre code pour mettre en œuvre - éventuellement. Je mettrais des interfaces dans un assemblage externe si vous vous attendez à ce que plusieurs assemblées dans votre projet ne soient pas sur elles - cela peut aider à rompre les dépendances de couplage. J'ai également utilisé cette pratique pour résoudre des problèmes de référencement circulaire, lorsque les assemblages doivent être conscients des interfaces les unes des autres. P>
Je ne mettez pas d'interfaces utilisées uniquement en interne dans un projet dans un assemblage séparé. Je ne promouve pas non plus les interfaces dans leur propre assemblée lorsque mes projets sont relativement petits - ou les interfaces ne sont pas destinées à être utilisées sans l'assemblage qui en dépend. P>
Quant à l'exemple que vous avez présenté - je vous suggère d'envisager de ne pas référencer les classes de votre système à partir d'interfaces. Dans la mesure du possible, j'essaie d'avoir des interfaces uniquement référence d'autres interfaces - cela empêche les choses relativement découplées. Vous ne pouvez pas toujours y parvenir - et donc lorsque vous avez ces types d'interfaces - vous devez les conserver avec l'assemblage qu'ils dépendent. P>
Si vous décidez de mettre des interfaces dans un assemblage séparé - vous ne devez pas nécessairement les mettre dans un seul assemblage. Vous voudrez peut-être les briser par leur utilisation prévue - de cette façon, les consommateurs peuvent tirer simplement les interfaces qui sont pertinentes pour un domaine particulier de fonctionnalité. P>
Merci pour votre réponse. J'essayais d'avoir la tête autour du trempet (principe d'inversion de dépendance). Bien qu'il soit beau en théorie (classes de niveau inférieur en fonction des classes de niveau supérieur et non de l'inverse), il est difficile de mettre en œuvre et de maintien dans la pratique. Il est tellement plus facile de conserver des interfaces avec les classes qui les implémentent. Je suppose que dans ce cas, je suis d'accord avec votre suggestion de "compliquer" la conception de cette manière, si elle devient nécessaire.
Je pense que les dépendances cycliques peuvent être inévitables, même si vous déclarez tout comme des interfaces, car il pourrait y avoir une méthode de montage FOO qui prend un paramètre ibar et une méthode dans la barre d'assemblage, qui prend un paramètre ifoo. P >
Je dirais qu'il n'y a pas de recette universelle pour cela, mais vous devriez plutôt utiliser "sens commun" pour diviser les interfaces dans les assemblages au besoin. P>