S.O.L.I.D.Princípios de Design para Programação Orientada
a Objetos
O Código Apodrece
Inevitável Exemplo de correção de bug
Acoplamento Mudança em uma linha de código gera
mudanças em outras tantas Nós temos que nos munir de armas
contra o apodrecimento do código SOLID é uma das armas
S.O.L.I.D.
Desenvolvimento de Sistemas não é um jogo Jenga
Princípios
Single Responsibility Principle Princípio de Responsabilidade Única
Open Closed Principle Princípio Aberto Fechado
Liskov Substitution Principle Princípio da Substituição de Liskov
Interface Segregation Principle Princípio da Segregação de Interface
Dependency Inversion Principle Princípio da Inversão de Dependência
Vantagens
Fácil de manter, adaptar e ajustar às constantes mudanças exigidas pelos clientes
Fácil de entender e testar Menor esforço para manutenções Melhor reaproveitamento de código
Princípio de Responsabilidade Única
Todo objeto deve ter uma única responsabilidade, e todos os seus serviços devem estar rigorosamente alinhados com aquela responsabilidade.
Princípio de Responsabilidade Única
Sintomas quando o princípio não é seguido: Quantas vezes abrimos um código e
simplesmente não temos a mínima ideia do que ele está fazendo?
Quantas variáveis espalhadas, aparentemente sem sentido?
Quantos cálculos mentais temos que fazer para descobrir se vai entrar naquele IF?
E quando a barra de rolagem parece não ter fim?
Princípio de Responsabilidade Única
Uma classe ou método deve ter uma e apenas uma razão para mudar
Quebrando o princípio: TransmissaoRepositorio
Seguindo o princípio: TransmissaoRepositorio ConversorTransmissao ControladorDiscoRigido ControladorEmail
Princípio Aberto Fechado
Cirurgia de peito aberto não é necessário ao colocar um casaco.
Princípio Aberto Fechado
Sintomas quando o princípio não é seguido: Adicionar novas regras requer mudança
sempre no mesmo pedaço de código Cada mudança pode introduzir bugs e
requer novos testes Mudar um pedaço de código cria mudança
em cascata em várias classes. If-ElseIf-Else encadeados Switch-Case
Princípio Aberto Fechado
Aberto para extensão Novo comportamento pode ser adicionado
no futuro Fechado para modificação
Não há necessidade de modificar o código Como adicionar novo comportamento
sem mudar o código? Depender de abstrações: Interfaces ou
Classes Abstratas
Princípio Aberto Fechado
Quebrando o princípio: Carrinho
Seguindo o princípio: Carrinho CalculadorPreco IRegraPreco RegraPrecoEspecial RegraPrecoPorGrama RegraPrecoCada
Substituição de Liskov
Caso se pareça um pato e grasne como um pato mas precise de baterias, você provavelmente possui a abstração errada.
Substituição de Liskov
Os subtipos devem ser substituíveis pelos seus tipos base.
Sintoma quando o princípio não é seguido: Usar o operador “is” ou “typeof” em
condições if-else ou switch
Substituição de Liskov
Quebrando o princípio: Retangulo Quadrado
Seguindo o princípio: Forma Retangulo Quadrado
Quadrado só é um retângulo no mundo real. Essa abstração “é-um” nesse caso não é válida.
Segregação de Interface
Você quer que eu plugue isso onde?
Segregação de Interface
Clientes não devem ser forçados a dependerem de métodos que eles não usam
Sintomas quando o princípio não é seguido: Interfaces com vários métodos, “gordas” Quebra o princípio de Responsabilidade Única Implementar uma interface “gorda” e nos
métodos que não quer implementar lançar uma exceção Por exemplo: método não suportado Ou throw new NotImplementedException()
Segregação de Interface
Quebrando o princípio Contato ControladorEmail Discador
Seguindo o princípio: IDiscavel IEmail Contato ControladorEmail Discador
Inversão de Dependência
Você soldaria uma lâmpada diretamente no fio de eletricidade na parede?
Inversão de Dependência
Um módulo de alto nível não deve depender de outros de baixo nível Baixo nível: acesso a banco, arquivos, WebServices Alto nível: regras e entidades de negócio, interação
com usuário Módulos de alto nível devem utilizar um
mecanismo para obter os dados de baixo nível, mas não depender dos detalhes desse mecanismo
UI depender do módulo de persistência, por exemplo banco de dados Se a persistência mudar para arquivo Xml, toda a UI
terá que ser reescrita
Inversão de Dependência
Sintomas: Dentro de um módulo/classe/método
instanciar uma classe explicitamente usando o operador “new”
Possuir referência do projeto de acesso a dados no projeto de UI
O ideal é sempre depender de abstrações: Interfaces ou classes abstratas
Inversão de Dependência
TransmissaoRepositorio
ControladorEmailConversorTransm
issao
Inversão de Dependência
TransmissaoRepositorio
IControladorEmail
IConversorTransmissao
ConversorTransmissao
ControladorEmail
Inversão de Dependência
Aplicando o princípio nos exemplos: SingleResponsibility OpenClosed
Referências
Software Practices, Pluralsight Principles of Object Oriented Design Design Patterns
Clean Code A Handbook of Agile Software Craftsmanship, Robert C. Martin
Agile Principles, Patterns, and Practices in C#, Robert C. Martin