Programação-microsoft-inoveduc-destaque
Compartilhar no facebook
Compartilhar no twitter
Compartilhar no linkedin
Diurno

Adote os princípios SOLID – Boas práticas de programação

É extremamente importante implementar softwares adotando boas práticas de programação. Elas propiciam o desenvolvimento de um código limpo, legível e testável. Diante dessa perspectiva, os sistemas atualmente implementados pela dti digital crafters são embasados nos princípios SOLID proposto por Robert C. Martin, por volta do ano 2000.

Propomos neste material abordar algumas violações x código adequado de acordo com os princípios instituídos pelo SOLID.

Princípio SSRP – Single responsibility principle

Observe a seguinte classe:

Acredita que o método dicionarUmaNovaPessoa() deveria ser responsável por realizar tantas coisas? Como definir o modelo dos dados persistentes da aplicação, instanciar conexão e realizar manipulação de dados no banco? A solução para esse problema pode ser apontado a seguir:

Note que a organização dos arquivos foi alterada, agora as classes estão divididas de acordo com as suas responsabilidades.
As classes CPFServices.cs e EmailServices.cs são responsáveis por validar os dados de CPF e E-mail da pessoa que se pretende cadastrar.



O método EValida() destas classes garante a validação dos dados, perceba que estes métodos são chamados na classe Pessoa.cs que contém os dados persistentes da aplicação (como um espelho da estrutura do banco de dados).

A classe PessoasRepository.cs responsabiliza-se pelo gerenciamento dos dados, logo a instanciação de conexão e definição dos métodos de adição de dados no Sistema Gerenciador de Banco de Dados (SGBD) devem ser definidos nesta classe. (Obs.: Isso ainda irá ser melhorado, não levem como verdade absoluta rsrs).

Por fim, a classe PessoaService.cs valida os dados e realiza o cadastro da Pessoa, com base nos métodos e classes que agora estão separados de acordo com sua responsabilidade.

Princípio OOCP – Open/Close principle

Neste exemplo, criou-se uma classe enum para armazenar os turnos.

Uma classe RemuneraçãoPorTurnos também foi criada para implementar o salário que algum funcionário recebe por cada turno, dessa forma bastaria alterar esta classe de acordo que surgissem novas demandas de turnos e acrescentar um if com a lógica correspondente à mudança.

Porém alterar uma classe já em funcionamento não é legal =( . Pensando nisso, podemos adicionar uma classe RemuneracaoBase que possa ser implementada por cada turno com sua lógica correspondente. Tal classe pode ser extensível para suas classes derivadas e fechada apenas naquele escopo que pretende atender. Veja o exemplo:

Quero agora a remuneração para o turno matutino, assim:

Princípio LLSP – Liskov substitution principle

Princípio de substitução de Liskov , pode ser apresentado pela seguinte diagramação UML:


Salienta-se que a classe Quadrado é similar à classe Retangulo, porém com uma característica especial: a largura e a altura são iguais. Logo, à primeira vista tudo parece correto (principalmente de forma conceitual, pois um quadro é um caso especial de um retângulo). Na notação UML classe Quadrado se apresenta com uma classe derivada e a classe retângulo configura-se como a classe base.

Note que na classe Retangulo, definiu-se a altura, largura e uma função para cálculo de área. E diante do nosso contexto, a classe Quadrado deve herdar de retângulo e sobreescrever seus métodos.

Porém , como a classe quadrado herda de retângulo, está também herdará a altura e largura da classe base. Isso não faz sentido, pois a altura e largura do retângulo não são iguais, o que descaracteriza as propriedades de um quadrado.

A solução é simples:

Ao definir a classe paralelogramo, é possível atribuir os dados de altura e largura corretos para cada uma das figuras geométricas, com isso o cálculo da área será feito corretamente.

Princípio IISP – Interface segragation principle

Um claro exemplo da utilização de interfaces generalistas demais pode ser apresentado a seguir:

Perceba que a interface ICadastroGeral possui métodos para validar as informações, salvá-las no banco de dados e enviar e-mail confirmando o cadastro. Mas esses métodos são aplicáveis a todas as classes que implementam a interface?

Perceba que para a classe de CadastroMercadoria a interface não seria aplicável, pois uma mercadoria não possui um e-mail. Pense em criar interfaces específicas, não importa quantas interfaces tem sua solução desde que sejam aplicáveis a todos os casos! =)

Princípio DDIP – Dependency Invension Principle

O princípio de inversão de dependências diz respeito à depender de uma abstração e não de uma implementação. Nesse caso, todos os demais princípios são aplicados, garantindo que os sistemas sejam o mais desacoplados e coesos possível. Para isso, recomenda-se trabalhar com a injeção de dependências. Em linhas gerais, “Injetar” uma dependência, nada mais é que passar uma classe (habitualmente uma classe interface) que será utilizada, para outra que irá consumir seus recursos.

Diante do que foi apresentado até aqui, a proposta do DDIP é prover um conjunto de interfaces específicas, classes que trabalhem com responsabilidade única e que sejam fechadas no seu escopo e abertas para extensão.

A classe PessoaServices.cs é neste caso, responsável por controlar as manipulações e verificações de dados da pessoa que for cadastrada no sistema. Neste caso, o construtor desta classe, está assim definido:

Perceba que para adicionar uma nova pessoa neste exemplo, será preciso injetar duas classes para validação e adição de dados. Dessa forma, para que seja possível construir uma classe PessoaServices é preciso passar a referência das interfaces IEmailServices e IPessoaRepository.

Note que o método AdicionarPessoa(Pessoa pessoa), é responsável apenas por adicionar uma nova pessoa, delegando à _pessoaRepository adicionar os dados dessa pessoa em um repositório de informações (pode ser um banco de dados, em memória, dentre outros) e à _emailServices enviar um e-mail comunicando que a pessoa foi cadastrada com sucesso !
Esperamos que este artigo seja útil a todos para entendimento e adoção do SOLID em suas aplicações. Obrigado !

Referências – Princípios SOLID

https://www.devmedia.com.br/padrao-de-injecao-de-dependencia/18506
https://medium.com/thiago-aragao/solid-princ%C3%ADpios-da-programa%C3%A7%C3%A3o-orientada-a-objetos-ba7e31d8fb25