Je travaille sur un projet logiciel dans lequel nous devons construire trois API. Un pour le canal de banque à domicile , un pour le canal d' agence et un troisième pour le canal de téléphonie mobile .
L'API de l'agence est la plus complète, car elle possède toutes les fonctionnalités. Ensuite, une API Home un peu plus petite, puis une API mobile.
Les architectes ont créé ici une couche commune (services EJB multicanaux partagés par toutes les API). Mais alors les API sont différentes.
Il n'y a pas de grande différence pour le moment entre les API. La grande équipe a commencé avec le canal de l'agence, et nous l'adaptons maintenant pour le canal domestique. Nous enrichissons simplement les objets de notre application personnelle. Sinon, le code est similaire à 95% entre les API. Les API sont construites sur Spring MVC , et elles ont (contrôleurs, modèles et certains utilitaires).
Fondamentalement, les contrôleurs font le mappage de BO vers ChannelObject (il me semble que ce n'est pas le bon endroit pour le faire), ainsi que certains utilitaires et sérialiseurs supplémentaires. Tout est en double pour l'instant. Ils disent que la raison de la duplication est qu'ils veulent que les API soient indépendantes. "Si demain nous voulons un comportement différent pour le domicile que pour l'agence ou le mobile, nous ne lutterons pas!"
Y at-il un cas où nous devrions accepter le code en double?
Réponses:
La duplication peut être la bonne chose à faire, mais pas pour cette raison.
Dire "nous pourrions vouloir que ces trois emplacements dans la base de code se comportent de manière différente même si, à l'heure actuelle, ils sont identiques" n'est pas une bonne raison pour une duplication à grande échelle. Cette notion pourrait s’appliquer à tous les systèmes et servir à justifier toute duplication, ce qui n’est évidemment pas raisonnable.
Les doubles emplois ne devraient être tolérés que lorsque les supprimer serait globalement plus coûteux maintenant pour une autre raison loi).
Pour ce que vous faites, la bonne solution pourrait être, par exemple, d’extraire le comportement dupliqué à l’heure actuelle dans une stratégie ou un autre modèle modélisant le comportement sous forme de classes, puis d’utiliser trois instances de la même classe. De cette façon, lorsque vous ne voulez changer le comportement dans l' un des trois endroits, il suffit de créer une nouvelle stratégie et instancier que dans un seul endroit. De cette façon, il vous suffit d'ajouter quelques classes et de laisser le reste de la base de code presque complètement vierge.
la source
Sandi Metz, un ingénieur logiciel de renom et auteur dans l'écosystème Ruby, a un grand billet de blog et un discours où elle parle aussi de la relation entre la duplication et l' abstraction. Elle arrive à la conclusion suivante
Et je suis complètement d'accord avec elle. Permettez-moi de vous donner plus de contexte à cette citation. Il est parfois très difficile de trouver la bonne abstraction. Dans de tels cas, il est tentant de choisir n'importe quelle abstraction pour réduire les doubles emplois. Mais plus tard, vous découvrirez peut-être que votre abstraction ne tient pas dans tous les cas. Cependant, il est coûteux de tout changer à nouveau et d’emprunter un autre chemin (pour une explication bien meilleure, regardez-la parler!).
Alors oui, pour moi, il y a des cas exceptionnels, où accepter le double emploi est la bonne décision, en particulier lorsque vous n'êtes pas sûr de ce qui va arriver et que les exigences vont probablement changer. D'après votre message, je déduis qu'il y a beaucoup de doublons à présent, mais vos collègues suggèrent que cela pourrait changer et que les deux applications ne soient pas couplées l'une à l'autre. À mon avis, cet argument est valable et ne peut être négligé en général.
la source
Si les gens commencent à raisonner sur le design avec les mots "si demain" , c'est souvent un grand signe d'avertissement pour moi, en particulier lorsque cet argument est utilisé pour justifier une décision qui implique du travail et des efforts supplémentaires, pour lesquels personne ne sait vraiment si rentable et qu’il est plus difficile de changer ou de revenir que la décision opposée.
La duplication de code ne réduit l'effort que pour un court terme, mais accroît les efforts de maintenance presque immédiatement, proportionnellement au nombre de lignes de code dupliquées. Notez également qu’une fois le code dupliqué, il sera difficile de supprimer cette duplication s’il s’avère que la décision est mauvaise. Tandis que si vous ne dupliquez pas le code maintenant, il est toujours facile d’introduire la duplication plus tard si cela reste conforme à DRY. était la mauvaise décision.
A déclaré que, dans les grandes organisations, il est parfois avantageux de privilégier l'indépendance de différentes équipes par rapport au principe DRY. Si la suppression de la duplication en extrayant les 95% de parties communes des API deux, un nouveau composant conduit à un couplage de deux équipes par ailleurs indépendantes, cela pourrait ne pas être la décision la plus sage. Par contre, si vos ressources sont limitées et qu’une seule équipe gère les deux API, je suis sûr que leur propre intérêt est de ne pas créer un double effort et d’éviter toute duplication inutile de code.
Notez en outre que cela fait une différence si les API "Home" et "Agency" sont utilisées exclusivement par des applications totalement différentes, ou si on peut essayer d'écrire un composant construit au-dessus de ces API pouvant également être utilisé dans un contexte "Home" comme dans un contexte "d'agence". Dans cette situation, avoir les parties communes des API parfaitement identiques (ce que vous ne pouvez garantir que si les parties communes ne sont pas dupliquées) facilitera probablement le développement d'un tel composant.
Donc, s'il s'avère qu'il y aura vraiment des sous-équipes différentes, chacune responsable de chacune des API, chacune avec un calendrier et des ressources différentes, alors il est temps de dupliquer le code, mais pas "au cas où".
la source
Duplication pour éviter le couplage . Disons que vous avez deux gros systèmes et que vous les forcez à utiliser la même bibliothèque. Vous pouvez coupler le cycle de libération des deux systèmes. Ce n'est peut-être pas si grave, mais disons qu'un système doit introduire un changement. L'autre doit analyser le changement et peut être affecté. Parfois, cela peut casser des choses. Même si les deux parties sont capables de coordonner les changements, cela pourrait prendre beaucoup de réunions, passer par les gestionnaires, les tests, les dépendances et la fin de la petite équipe autonome.
Donc, vous payez le prix du code dupliqué pour gagner en autonomie et en indépendance.
la source