ASPNET SOLID C# Principles — Single Responsability

Nicolas Fontes
5 min readMay 17, 2019

--

Dando início na série de posts referentes aos princípios SOLID em programação .Net C#, hoje quero detalhar um pouco mais da minha vida com experiência nesse princípio e mostrar um exemplo REAL de como você pode começar a mudar seu jeito de programar o mais logo possível.

Vamos começar entrando em um acordo claro de que um método com muitas linhas (acima de 30 já é muito) já simboliza que tem alguma coisa errado né?

Confesso que desde o início da minha carreira, nunca me apeguei a esse detalhe de o quão era feio e inviável métodos “gigantes”. Toda vez que precisava de manutenção ou expansão era um sacrifício para poder encontrar o local, saber onde modificar, testar as dezenas de maneiras de execução e garantir que quando publicasse, iria funcionar! Sem ainda dizer, que muitas vezes dava para ver o mesmo trecho de código em 2 locais diferentes! (as vezes, até, em classes totalmente diferentes).

Depois de conhecer, aprender e utilizar o conceito de Responsabilidade Única, comecei a me deparar com gigante evolução de qualidade de código em meus projetos. Nessa época eu já era codereviewer de outros desenvolvedores e pude, aos poucos, ir mostrando isso para eles e conquistando-os para também realizarem essas mudanças.

Hoje em dia esse conceito é muito claro pra mim, é aplicado em 100% dos meus projetos e eu só tenho a ganhar com isso porque além de não ter replicamento de código (posso reutilizar o mesmo código quando preciso), é fácil de dar manutenção, criar testes para métodos específicos e poder liberar o código a outro desenvolvedor para seguir com desenvolvimento.

Exemplo Prático

Para mostrar na prática como utilizar o conceito de Responsabilidade Únida do SOLID, eu criei um simples projeto Console Application no Visual Studio e desenvolvi a seção de PROBLEMA e a seção de SOLUÇÃO. Lembrando que o intuito desse projeto é realmente mostrar a ação de responsabilidade única dos métodos. Caso você queira ter acesso ao código, basta acessar meu GitHub.

A arquitetura do projeto que criei ficou assim:

Arquitetura do Projeto

Lembrando que o intuito não é mostrar DDD ou alguma outra arquitetura de software. Mas aqui na imagem acima, dentro da pasta Solution, o mais ideal seria colocar User dentro de uma pasta Model, as classes repository na camada de repository e a classe de serviço na camada service.

Onde o Program é meu programa principal que vai ser iniciado e se comunica com as classes especificas que eu mostrarei em cada etapa abaixo.

Classe Principal do Software

Exemplo Problema

Assim que funciona a região de chamar o método problema dentro do Program.

Região Problema dentro do Program.cs

Nesse projeto só tem uma classe de utilização que é o User.cs

Classe User.cs dentro de Problem

Vamos analisa-la:

  • É uma classe com o NOME para classes entidades, porém há serviços dentro dela.
  • Tem a connectionString do banco de dados dentro dela.
  • Tem as propriedades do objeto User
  • Tem o método de Salvar um usuário com as funções de validar os campos, criar a conexão com o banco, adicionar os parâmetros, executar a ação, fechar comunicação com o banco e retornar o valor.

Tirando o item de ter as propriedades do objeto User, o resto realmente não deveria estar ai! Imagina que a gente precise mudar o local do banco. Vamos ter que modificar a classe que deveria gerenciar apenas o usuário do sistema também. Isso não faz sentido. Além de que, se eu criasse uma classe para outro módulo (exemplo: Cliente) eu precisaria ter connectionString, abrir e fechar conexão também lá. Já temos códigos duplicados.

Funciona, mas é o pior caminho a tomar para desenvolver essa funcionalidade!

Teste Solução

Já começamos a ver diferença já na região Solução dentro do Program.cs. Pois agora estou instanciando classes diferentes para funções diferentes.

Região Solução dentro de Program.cs

Vamos dar uma olhada na classe User agora:

Classe User no Projeto Solução

Primeiro que eu já crio o objeto usuário lá dentro da classe User. Não sendo no “cliente” do serviço. Mas vamos ver mais detalhes

E como ficou a classe de serviço do Usuário:

Primeiramente agora é ela a responsável por instanciar a classe de comunicação com o banco e de conexão do usuario com o banco de dados. Por que? Pelo simples fato que na minha classe de cliente (Program.cs) eu posso querer apenas chamar serviços de e-mail ou outros que não necessitam de banco, então não tem necessidade de eu criar uma instancia para isso se eu não vou usar.

Veja também que criei um método INTERNO de validação dos campos de usuário. Sei que está bem simples a validação, mas o intuito desse post é mostrar a responsabilidade. Ele simplesmente retorna se passou a validação ou não.

Só depois de validado que eu abro a conexão com o banco, porque agora sim eu sei que precisarei me comunicar com o banco de dados para executar alguma coisa. Veja só como ficou isso:

Classe ConnectionRepository

Eu simplesmente tenho 2 métodos que usam a mesma variável, porém para ações diferentes (abrir e fechar conexão).

Depois de validado os campos, objeto criado e conexão aberta, agora é hora do objeto de repositório executar sua função:

Classe UserRepository

Para isso veja a classe UserRepository onde eu só tenho meu método de Salvar Usuário, que eu recebo o objeto, crio o comando, adiciono os parâmetros e executo minha função. Simples assim!

Após isso basta eu fechar a conexão e retornar para o usuário o sucesso ao realização a ação. (veja a imagem UserService).

Finalizando..

Viu só como aplicar o conceito de Responsabilidade Únida não é um bicho de 7 cabeças e você pode tornar seu código mais legível possível. Isso é fácil, rápido e simples! Só precisa começar a se apegar nesse detalhe.

Se você quiser o código desse projeto, está disponível no meu Github junto com os demais conceitos que estarei falando nos próximos posts!

Link aqui

Obrigado e Até mais =D

--

--

Nicolas Fontes

.Net Developer, living and working in Ireland. My goal here is help developers to evolve theirs knowledge. Let`s do it together! http://nicolasfontes.com.br