Princípios SOLID - MarcosPiccoli/DotNetPractices GitHub Wiki

Princípios SOLID

O SOLID é um acrônimo criado por Michael Feathers, baseando-se nos princípios da programação orientada a objetos, sendo:

S — Single Responsiblity Principle (Princípio da responsabilidade única) O — Open-Closed Principle (Princípio Aberto-Fechado) L — Liskov Substitution Principle (Princípio da substituição de Liskov) I — Interface Segregation Principle (Princípio da Segregação da Interface) D — Dependency Inversion Principle (Princípio da inversão da dependência)

SRP - Single responsibility principle

Uma classe deve ter um, e somente um, motivo para ser modificada.

Esse princípio declara que uma classe deve ser especializada em um único assunto e possuir apenas uma responsabilidade dentro do software, ou seja, a classe deve ter uma única tarefa ou ação para executar.

Quando estamos aprendendo programação orientada a objetos, sem sabermos, damos a uma classe mais de uma responsabilidade e acabamos criando God Classes. Num primeiro momento isso pode parecer eficiente, mas como as responsabilidades acabam se misturando, quando há necessidade de realizar alterações nessa classe, será difícil modificar uma dessas responsabilidades sem comprometer as outras. Toda alteração acaba sendo introduzida com um certo nível de incerteza em nosso sistema — principalmente se não existirem testes automatizados!

God Class — Classe Deus: Na programação orientada a objetos, é uma classe que sabe demais ou faz demais.

A violação do SRP pode gerar alguns problemas, sendo eles: Falta de coesão: uma classe não deve assumir responsabilidades que não são suas; Alto acoplamento: Mais responsabilidades geram um maior nível de dependências, deixando o sistema engessado e frágil para alterações; Dificuldades na implementação de testes automatizados: É difícil de “mockar” esse tipo de classe; Dificuldades para reaproveitar o código; {.is-info}

o SRP é um dos princípios mais importantes da orientação a objeto, ele acaba sendo a base para outros princípios e padrões porque aborda temas como acoplamento e coesão, características que todo código orientado a objetos deveria ter.

Aplicando esse princípio, automaticamente você estará escrevendo um código mais limpo e de fácil manutenção! Se você tem interesse nesse assunto

OCP - Open/closed principle

Objetos ou entidades devem estar abertos para extensão, mas fechados para modificação, ou seja, quando novos comportamentos e recursos precisam ser adicionados no software, devemos estender e não alterar o código fonte original.

Mas não seria mais fácil apenas acrescentar mais um IF e fazer alguma verificação aplicando as respectivas regras?

Sim, e provavelmente essa seria a solução que qualquer programador menos experiente iria fazer. Contudo, esse é exatamente o problema! Alterar uma classe já existente para adicionar um novo comportamento, corremos um sério risco de introduzir bugs em algo que já estava funcionando. {.is-info}

Open-Closed Principle também é base para o padrão de projeto Strategy, sua principal vantagem é a facilidade na adição de novos requisitos, diminuindo as chances de introduzir novos bugs pois o novo comportamento fica isolado, e o que estava funcionando provavelmente continuara funcionando.

LSP - Liskov Substitution Principle

Uma classe derivada deve ser substituível por sua classe base.

Seguir o LSP nos permite usar o polimorfismo com mais confiança. Podemos chamar nossas classes derivadas referindo-se à sua classe base sem preocupações com resultados inesperados.

ISP — Interface Segregation Principle

Uma classe não deve ser forçada a implementar interfaces e métodos que não irão utilizar.

Esse princípio basicamente diz que é melhor criar interfaces mais específicas ao invés de termos uma única interface genérica.

DIP — Dependency Inversion Principle

Provavelmente você já ouviu a seguinte frase: "Programe para uma interface e não para uma implementação." Esse princípio é essencialmente isso, podendo ser definido da seguinte maneira:

  • Módulos de alto nível não devem depender de módulos de baixo nível. Ambos devem depender da abstração.
  • Abstrações não devem depender de detalhes. Detalhes devem depender de abstrações.

Obs: Módulo de alto nível é um módulo que depende de outros módulos.

Inversão de Dependência não é igual a Injeção de Dependência! A Inversão de Dependência é um princípio (Conceito) e a Injeção de Dependência é um padrão de projeto (Design Pattern). {.is-warning}

Temos um Dojo que aborda esse assunto, acesse aqui para conferir todos nossos dojos {.is-info}