DEV Community

mylena
mylena

Posted on

Guia: O que é SOLID

Disclaimer: Post com intuito de gravar meu aprendizado em boas práticas de desenvolvimento. Não é uma verdade absoluta.

Referência: Arquitetura Limpa, Robert C. Martin


SOLID é um conjunto de princípios que facilitam a codificação/entendimento de um desenvolvedor e a manuntenção do software.

1. S: Princípio da Responsabilidade Única

Refatorar uma função quebrando ela em partes menores não é, necessariamente, o princípio da responsabilidade única. No caso, o SRP diz sobre um módulo ser responsável por apenas um ator.

Exemplo que não atende o princípio:

Uma classe Funcionário que armazena as regras de diferentes departamentos: TI, RH e Financeiro. Cada departamento tem sua lógica na classe, porém eles compartilham um mesmo método. Se eu precisar alterar esse método para atender uma demanda do RH, ele vai acabar impactando as lógicas do TI e Financeiro.

Ou seja, nesse cenário, a violação se dá por atender a vários atores (TI, RH e Financeiro) e compartilhar o mesmo código que é volátil entre lógicas diferentes.

Remodelando para atender o princípio:

Uma forma básica para atender o SRP seria separar as responsabilidades de cada ator. A classe base continua sendo a de Funcionário e ela é responsável por armazenar regras que sejam genéricas e que atendam a todos igualmente.

Dessa forma, seria criado classes distintas: TI, RH e Financeiro. Podendo herdar da base Funcionário e implementar suas próprias regras específicas.

Outros tipos de violações:

  • Misturar regra de negócio e persistência em uma só classe
  • Adicionar diferentes tipos de responsabilidades em um só lugar apenas por ser da mesma entidade.

Vale ressaltar que esse princípio não se refere apenas a classes, podendo dividir serviços/métodos, o importante é atender a um único ator/módulo, dependendo do escopo.

2. O: Princípio Aberto/Fechado

O OCP diz que uma classe/método deve estar aberta para extensão, mas fechada para modificação. Esse princípio é a base pro padrão Strategy.

Quando existirem novas funcionalidades, é preferível estender do que alterar o código principal que já funciona pois pode aparecer bugs que não existiam antes.

Uma boa prática é usar Interfaces e DI ao criar novas funcionalidades e estabelecer a comunicação.

Exemplo:

Uma classe Desconto com subclasses como DescontoPorcentagem e DescontoValorFixo, onde as regras de Desconto pode ser extendida de acordo com cada tipo específico de desconto.

3. L: Princípio de Substituição de Liskov

O LSP fala que uma classe derivada deve ser substituível por sua classe base. Ou seja, uma classe derivada deve manter a herança sem modificá-la e ser usada como se ela mesma fosse a classe base.

Exemplo:

Código em C# que define duas classes: Retangulo e Quadrado. A classe Retangulo possui propriedades Largura e Altura com métodos getter e setter, além de um método CalcularArea que retorna o produto de largura e altura. A classe Quadrado herda de Retangulo e redefine as propriedades Largura e Altura para garantir que ambos os valores sejam sempre iguais, ajustando largura e altura simultaneamente.

No exemplo acima, o LSP é ferido tendo em vista que a classe Quadrado está modificando o comportamento original da classe Retangulo.

O correto seria criar uma classe abstrata ou interface para calcular a área e extender nas classes Quadrado e Retangulo, fazendo as respectivas mudanças para os seus contextos.

Então o OCP também ferido quando há essa violação do LSP.

4. I: Princípio da Segregação de Interface

O ISP diz para quebrar as classes em interfaces e direcionar para cada ator específico para evitar depender de módulos que tenha mais elementos do que o necessário.

Ou seja, uma classe não deve ser forçada a usar implementações que não vai precisar utilizar no seu contexto. É preferível ter interfaces específicas do que genéricas.

5. D: Princípio da Inversão de Dependência

O DIP diz que sistemas mais flexíveis são os que se referem apenas a abstrações, ou seja, os import/include/use devem se referir apenas a interfaces, classes abstratas ou qualquer outra declaração que não seja concreta.

A partir dessa ideia de usar abstrações, existe o Factory para ajudar no constrole das injenções de dependências.

Top comments (0)