Escrevo muito código que envolve três etapas básicas.
- Obtenha dados de algum lugar.
- Transforme esses dados.
- Coloque esses dados em algum lugar.
Normalmente, acabo usando três tipos de classes - inspirados em seus respectivos padrões de design.
- Fábricas - para construir um objeto a partir de algum recurso.
- Mediadores - para usar a fábrica, execute a transformação e use o comandante.
- Comandantes - para colocar esses dados em outro lugar.
Minhas aulas tendem a ser muito pequenas, geralmente um método único (público), por exemplo, obter dados, transformar dados, trabalhar, salvar dados. Isso leva a uma proliferação de classes, mas em geral funciona bem.
Onde eu luto é quando chego aos testes, acabo fazendo testes fortemente acoplados. Por exemplo;
- Fábrica - lê arquivos do disco.
- Comandante - grava arquivos no disco.
Não posso testar um sem o outro. Eu poderia escrever código 'teste' adicional para fazer leitura / gravação em disco também, mas depois estou me repetindo.
Olhando para .Net, a classe File adota uma abordagem diferente, ela combina as responsabilidades (da minha) fábrica e comandante. Possui funções para criar, excluir, existir e ler em um só lugar.
Devo procurar seguir o exemplo de .Net e combinar - principalmente ao lidar com recursos externos - minhas aulas juntos? O código ainda está associado, mas é mais intencional - acontece na implementação original, e não nos testes.
É minha questão aqui que apliquei o Princípio de Responsabilidade Única de maneira um tanto exagerada? Tenho aulas separadas, responsáveis pela leitura e gravação. Quando eu poderia ter uma classe combinada responsável por lidar com um recurso específico, por exemplo, disco do sistema.
Looking at .Net, the File class takes a different approach, it combines the responsibilities (of my) factory and commander together. It has functions for Create, Delete, Exists, and Read all in one place.
- Observe que você está confundindo "responsabilidade" com "coisa a fazer". Uma responsabilidade é mais como uma "área de preocupação". A responsabilidade da classe File está executando operações de arquivo.
File
biblioteca do C # é que, pelo que sabemos, a File
classe pode ser apenas uma fachada, colocando todas as operações de arquivo em um único local - na classe, mas poderia estar internamente usando classes de leitura / gravação semelhantes às suas, o que na verdade, contém a lógica mais complicada para manipulação de arquivos. Essa classe (the File
) ainda aderiria ao SRP, porque o processo de realmente trabalhar com o sistema de arquivos seria abstraído por trás de outra camada - provavelmente com uma interface unificadora. Não estou dizendo que é o caso, mas poderia ser. :)