Je comprends ce que SOLID est censé accomplir et je l'utilise régulièrement dans des situations où la modularité est importante et ses objectifs sont clairement utiles. Cependant, deux choses m'empêchent de l'appliquer de manière cohérente dans ma base de code:
Je veux éviter une abstraction prématurée. D'après mon expérience, tracer des lignes d'abstraction sans cas d'utilisation concrets (du genre de ceux qui existent actuellement ou dans un avenir prévisible ) conduit à les tracer aux mauvais endroits. Lorsque j'essaie de modifier un tel code, les lignes d'abstraction gênent plutôt que d'aider. Par conséquent, j'ai tendance à me tromper en évitant de tracer des lignes d'abstraction jusqu'à ce que j'aie une bonne idée de l'endroit où elles seraient utiles.
Je trouve difficile de justifier l'augmentation de la modularité pour elle-même si cela rend mon code plus verbeux, plus difficile à comprendre, etc. et n'élimine aucune duplication. Je trouve que le code procédural ou objet Dieu simple et étroitement couplé est parfois plus facile à comprendre qu'un code ravioli très bien factorisé car le flux est simple et linéaire. C'est aussi beaucoup plus facile à écrire.
D'un autre côté, cet état d'esprit mène souvent à des objets divins. Je refaçonne généralement ces derniers de façon conservatrice, en ajoutant des lignes d'abstraction claires uniquement lorsque je vois des modèles clairs émerger. Qu'est-ce qui ne va pas avec les objets de Dieu et le code étroitement couplé si vous n'avez pas clairement besoin de plus de modularité, n'avez pas de duplication significative et le code est lisible?
EDIT: En ce qui concerne les principes SOLID individuels, je voulais souligner que la substitution de Liskov est à mon humble avis une formalisation du bon sens et devrait être appliquée partout, car les abstractions n'ont aucun sens si ce n'est pas le cas. En outre, chaque classe devrait avoir une responsabilité unique à un certain niveau d'abstraction, bien qu'il puisse s'agir d'un niveau très élevé avec les détails d'implémentation regroupés dans une énorme classe de 2 000 lignes. Fondamentalement, vos abstractions doivent avoir un sens là où vous choisissez d'abstraire. Les principes que je remets en question dans les cas où la modularité n'est pas clairement utile sont la fermeture ouverte, la ségrégation d'interfaces et surtout l'inversion de dépendance, car il s'agit de modularité, et pas seulement d'avoir des abstractions sensées.