Entendo o que o SOLID deve realizar e o uso regularmente em situações em que a modularidade é importante e seus objetivos são claramente úteis. No entanto, duas coisas me impedem de aplicá-lo consistentemente na minha base de código:
Eu quero evitar abstrações prematuras. Na minha experiência, desenhar linhas de abstração sem casos de uso concretos (do tipo que existe agora ou no futuro previsível ) os leva a serem desenhados nos lugares errados. Quando tento modificar esse código, as linhas de abstração atrapalham, em vez de ajudar. Portanto, tenho a tendência de errar ao não desenhar nenhuma linha de abstração até ter uma boa idéia de onde elas seriam úteis.
Acho difícil justificar o aumento da modularidade por si só, se isso torna meu código mais detalhado, mais difícil de entender etc. e não elimina nenhuma duplicação. Acho que o código processual simples, com procedimentos bem acoplados ou de objeto de Deus, às vezes é mais fácil de entender do que o código ravioli muito bem fatorado, porque o fluxo é simples e linear. Também é muito mais fácil escrever.
Por outro lado, essa mentalidade geralmente leva a objetos de Deus. Geralmente refatoro-as de maneira conservadora, adicionando linhas de abstração claras apenas quando vejo padrões claros emergindo. O que há de errado com os objetos de Deus e com o código fortemente associado se você não precisar claramente de mais modularidade, não possui duplicação significativa e o código é legível?
EDIT: No que diz respeito aos princípios individuais do SOLID, eu quis enfatizar que a Substituição de Liskov é IMHO uma formalização do senso comum e deve ser aplicada em todos os lugares, pois as abstrações não fazem sentido se não forem. Além disso, todas as classes devem ter uma única responsabilidade em algum nível de abstração, embora possa ser um nível muito alto, com os detalhes da implementação compactados em uma enorme classe de 2.000 linhas. Basicamente, suas abstrações devem fazer sentido onde você escolhe abstrair. Os princípios que eu questiono nos casos em que a modularidade não é claramente útil são de abertura aberta, segregação de interface e especialmente inversão de dependência, já que se trata de modularidade, e não apenas abstrações que fazem sentido.