La question présente un faux dilemme. Une application correcte du principe YAGNI n’est pas une chose sans rapport. C'est un aspect d'un bon design. Chacun des principes SOLID sont également des aspects d’un bon design. Vous ne pouvez pas toujours appliquer pleinement tous les principes dans n'importe quelle discipline. Les problèmes du monde réel exercent beaucoup de pression sur votre code, et certains d'entre eux vont dans des directions opposées. Les principes de conception doivent en tenir compte, mais aucune poignée de principes ne peut s’adapter à toutes les situations.
Examinons maintenant chaque principe en sachant que, même s’ils peuvent parfois tirer des directions différentes, ils ne sont pas fondamentalement en conflit.
YAGNI a été conçu pour aider les développeurs à éviter un type de travail particulier: celui qui consiste à construire la mauvaise chose. Pour ce faire, il nous aide à éviter de prendre des décisions erronées trop tôt, sur la base d’hypothèses ou de prévisions concernant ce qui, à notre avis, changera ou sera nécessaire à l’avenir. L'expérience collective nous dit que lorsque nous faisons cela, nous avons généralement tort. Par exemple, YAGNI vous dirait de ne pas créer d'interface dans un but de réutilisation , à moins que vous ne sachiez maintenant que vous avez besoin de plusieurs implémenteurs. De même, YAGNI dirait de ne pas créer de "ScreenManager" pour gérer le formulaire unique dans une application, à moins que vous ne sachiez maintenant que vous allez avoir plusieurs écrans.
Contrairement à ce que beaucoup de gens pensent, SOLID n’est pas une question de réutilisabilité, de généricité ou même d’abstraction. SOLID est conçu pour vous aider à écrire du code préparé pour le changement , sans rien dire sur ce que ce changement pourrait être. Les cinq principes de SOLID créent une stratégie de code du bâtiment flexible sans être trop générique, ni simple sans naïf. Une application correcte du code SOLID génère de petites classes ciblées avec des rôles et des limites bien définis. Le résultat pratique est que, quel que soit le besoin, un minimum de classes doit être touché. Et de même, pour tout changement de code, il y a une quantité minimisée de "répercussions" sur les autres classes.
En regardant votre exemple de situation, voyons ce que YAGNI et SOLID pourraient avoir à dire. Vous envisagez une interface de référentiel commune car tous les référentiels ont la même apparence de l'extérieur. Mais la valeur d'une interface générique commune réside dans la possibilité d'utiliser n'importe lequel des implémenteurs sans avoir besoin de savoir laquelle il s'agit en particulier. À moins que cela ne soit nécessaire ou utile dans votre application, YAGNI vous recommande de ne pas le faire.
Il y a 5 principes SOLID à examiner. S est la responsabilité unique. Cela ne dit rien sur l'interface, mais pourrait en dire autant sur vos classes concrètes. On pourrait faire valoir que la gestion de l’accès aux données proprement dit pourrait être confiée à une ou plusieurs autres classes, tandis que la responsabilité des référentiels est de traduire un contexte implicite (CustomerRepository est un référentiel implicite pour les entités du client) en appels explicites aux utilisateurs. API d'accès aux données généralisées spécifiant le type d'entité client.
O est ouvert-fermé. Cela concerne principalement l'héritage. Cela s'appliquerait si vous essayiez de dériver vos référentiels à partir d'une base commune implémentant des fonctionnalités communes, ou si vous espériez dériver plus loin des différents référentiels. Mais vous ne l'êtes pas, alors ce n'est pas le cas.
L est la substituabilité de Liskov. Ceci s'applique si vous avez l'intention d'utiliser les référentiels via l'interface de référentiel commun. Il impose des restrictions sur l'interface et les implémentations pour assurer la cohérence et éviter une manipulation spéciale pour les différents développeurs. La raison en est que ce traitement spécial compromet le but d'une interface. Il peut être utile d’examiner ce principe car il peut vous empêcher d’utiliser l’interface commune du référentiel. Cela coïncide avec les conseils de YAGNI.
I est la ségrégation d'interface. Cela peut s’appliquer si vous commencez à ajouter différentes opérations de requête à vos référentiels. La ségrégation d'interface s'applique lorsque vous pouvez diviser les membres d'une classe en deux sous-ensembles, l'un étant utilisé par certains consommateurs et l'autre par d'autres, mais aucun consommateur n'utilisera probablement les deux sous-ensembles. Il est conseillé de créer deux interfaces distinctes plutôt qu'une interface commune. Dans votre cas, il est peu probable que l'extraction et la sauvegarde d'instances individuelles soient consommées par le même code que celui utilisé pour les requêtes générales. Il peut donc être utile de les séparer en deux interfaces.
D est l'injection de dépendance. Nous revenons ici au même point que le S. Si vous avez séparé votre consommation de l'API d'accès aux données dans un objet séparé, ce principe dit que plutôt que de simplement créer une instance de cet objet, vous devez la transmettre lorsque vous créez. un référentiel. Cela facilite le contrôle de la durée de vie du composant d'accès aux données, en offrant la possibilité de partager des références à ce dernier entre vos référentiels, sans qu'il soit nécessaire de le transformer en singleton.
Il est important de noter que la plupart des principes SOLID ne s'appliquent pas nécessairement à ce stade particulier du développement de votre application. Par exemple, si vous devez diviser l'accès aux données en fonction de la complexité de celui-ci et si vous souhaitez tester la logique de votre référentiel sans toucher à la base de données. Cela semble peu probable (malheureusement, à mon avis), ce n'est donc probablement pas nécessaire.
Après toutes ces considérations, nous constatons que YAGNI et SOLID fournissent en réalité un conseil commun solide et immédiatement pertinent: il n’est probablement pas nécessaire de créer une interface de référentiel générique commune.
Toute cette réflexion est extrêmement utile comme exercice d'apprentissage. Vous prenez beaucoup de temps à apprendre, mais avec le temps, vous développez votre intuition et devenez très rapide. Vous saurez ce qu'il faut faire, mais vous n'avez pas besoin de penser à tous ces mots à moins que quelqu'un vous demande d'expliquer pourquoi.