---
# System prepended metadata

title: Orientação a Objetos e SOLID para Ninjas
tags: [Clube do Livro, Basement]

---

# Orientação a Objetos e SOLID para Ninjas

###### tags: `Basement` `Clube do Livro`


## Capítulo 02 - A coesão e o tal do SRP
- Uma classe coesa é aquela que possui uma única responsabilidade.
- Possui menos código e seu reúso é maior.
- A chance de classes não coesas terem defeitos é enorme.
- Toda classe que não é coesa não para de crescer nunca.
- Só quebrar um método grande em vários pequenos não é reúso.
- O programador não deve nunca usar `CTRL+F` para programar e buscar pelos pontos de mudança.
- Existem exceções para decisões explícitas de design, como o padrão arquitetural MVC, etc.
  - O problema são as dependências implícitas.
- Métodos privados servem de apoio aos métodos públicos.
  - Eles ajudam a aumentar a legibilidade de nossos códigos.
  - Se seu método público crescer muito ou sofrer alterações constantes, talvez valha a pena extraí-lo para uma classe específica.
- A boa prática para controllers é fazer com que essas classes apenas coordenem processos.
- O **SRP ou Single Responsibility Principle** é o principío do SOLID que nos lembra da coesão.
- A classe deve ter uma, e apenas uma, razão para mudar.
- É fácil entender que a classe deve ter apenas uma responsabilidade.
  - O difícil é definir o que é uma responsabilidade.
- Dois comportamentos pertencem ao mesmo conceito/responsabilidade se mudam juntos.
- Escrever código de qualidade é incremental.
- Classes coesas são mais fáceis de serem mantidas, reutilizadas e tendem a ter menos bugs.

## Capítulo 03 - Acoplamento e o tal do DIP
- A máxima da orientação a objetos é que tenha classes que são muito coesas e pouco acopladas.
- O grande problema do acoplamento é que uma mudança em qualquer uma das classes pode impactar em mudanças na classe principal.
- A partir do momento em que uma classe possui muitas dependências, todas elas podem propagar problemas para a classe principal.
- As dependências de uma classe podem ter suas próprias dependências, gerando uma grande árvore de classes que devem ser levadas junto.
- Acoplamento bom é aquele em que a dependência é estável, como List e String.
  - Muda muito pouco ou quase nunca muda.
- Acoplamento é geralmente olhar quais classes de que uma determinada classe depende.
- Programar voltado para interfaces faz com que o código seja flexível e estável.
- Interfaces coesas são aquelas cujos comportamentos são simples e bem definidos.
  - Tendem a mudar menos e são mais reutilizáveis.
- A ideia de reduzir o problema do acoplamento não é deixar de acoplar, é começar a acoplar com módulos estáveis.
- **DIP ou Princípio da Inversão de Dependências** é aquele cuja ideia é: sempre que uma classe for depender de outra, ela deve depender sempre de outro módulo mais estável do que ela mesma.
- Se A depende de B, a ideia é que B seja mais estável que A.
  - Mas B depende de C, logo a ideia é que C seja mais estável que B.
- Andar sempre em direção à estabilidade.
- Abstrações tendem a ser estáveis e implementações instáveis.
- O princípio diz:
  - Módulos de alto nível não devem depender de módulos de baixo nível. Ambos devem depender de abstrações.
  - Abstrações não devem depender de detalhes. Detalhes devem depender de abstrações.
- Não confundir com injeção de dependência, que é a ideia de você ter os parâmetros no construtor e alguém injetar essas dependências para você.

## Capítulo 04 - Classes abertas e o tal do OCP
- Código deve estar sempre pronto para evoluir.
- A discussão é sobre balancear acoplamento e coesão.
- O que ajuda a ter classes coesas que evoluam facilmente é escrever classes que sejam abertas para extensão mas fechadas para modificação.
  - **Open Closed Principle**.
- Flexibilizar o código que realmente precisa de códigos flexíveis.
  - Seja criterioso, sejam simples em códigos que podem ser simples.
- Se está difícil de testar, o código pode ser melhorado.
- Classes abertas são aquelas que deixam explícitas suas dependências.
  - Assim podemos mudar as implementações concretas que são passadas para ela a qualquer momento, o que faz com que o resultado final da execução mude de acordo com as classes que foram passadas pra ela.
  - Mudar o comportamento sem mudar o código.

## Capítulo 05 - O encapsulamento e a propagação de mudanças
- Encapsulamento é o nome que damos à ideia de a classe esconder os detalhes de implementação.
  - Como o método faz o trabalho dele.
- Traz dois ganhos:
  - Facilidade para alterar a implementação.
  - Se o código não está bem encapsulado, isso implica em regras de negócio espalhadas por lugares diferentes.
- Uma classe (ou método) bem encapsulada é aquela que esconde bem a maneira como faz as coisas.
- A classe deve apenas deixar claro o que ela faz, quais são as operações que ela provê para as classes que farão uso dela.
- Intimidade inapropriada são códigos que entendem mais do que deveriam sobre o comportamento de outra classe.
- Tell, don't ask.
- Sistemas difíceis de se manter são aqueles que não pensam na propagação de mudança.
- A Lei de Demeter sugere que evitemos o uso de invocações em cadeia.
  - Para diminuir a propagação de mudanças.
- Antes de criar setters, pensar se eles não gerarão probelmas de encapsulamento no futuro.
- Fazer com que getters sempre devolvam cópias dos objetos originais ou bloqueiem a alteração de alguma forma.
- Como saber se classes e métodos estão encapsulados?
  - Olhar pra ela e perguntar/responder: o quê? Como?
    - O “o quê?” você tem que ser capaz de responder, porque o nome do método tem que lhe dizer isso.
    - O “como?” você não tem que conseguir responder. Se conseguir responder, não está encapsulado.

## Capítulo 06 - Herança x composição e o tal do LSP
- "Crie suas classes pensando em herança, ou então proíba-a".
- Classes filhas precisam respeitar os contratos definidos pela classe pai.
- **Liskov Substitutive Principle**
  - Toda classes tem as suas pré e pós-condições.
  - Pré-condições são os dados que chegam nela.
    - Quais são as restrições iniciais para que determinado método funcione corretamente?
  - Pós-condições são o que o comportamento devolve.
  - Uma pré-condição pode ser afrouxada, mas a pós-condição só pode ser apertada.
  - É sobre isso que o princípio L discute, ao herdar você deve sempre lembrar do contrato estabelecido pela classe pai.
- Uma classe filho é totalmente acoplada à classe pai.
- Modele hierarquias nas quais as classes filhos precisam conhecer pouco ou nada dos detalhes da classe pai.
- Se a classe filho conhece demais da implementação da classe pai, é porque ela não encapsulou bem seus detalhes de implementação.
- Evitar o uso de protected.
- Usar composição ao invés de herança.
- São vantagens da composição:
  - A relação da classe principal com a classe dependida não é tão íntima quanto a relação entre classes pai e filho.
  - Quebrar o encapsulamento é mais difícil.
  - Permite flexibilidade.
  - Facilidade de escrever testes automatizados.
- Quando usar herança?
  - Herança deve ser usada quando existe realmente a relação de X é um Y.
  - Não use herança caso a relação seja de composição, ou seja, X tem um Y, ou X faz uso de Y.
  - Use herança para reaproveitar código que realmente faz sentido, e composição para trechos de código que precisam de mais flexibilidade.
- Não descarte herança, apenas favoreça a composição.

## Capítulo 07 - Interfaces magras e o tal do ISP
- Princípio da segregação de Interface, ISP ou **Interface Segregation Principle**.
- Se uma interface não é coesa, dividimos em duas ou mais interfaces.
- Dessa forma, cada classes filha implementa quais interfaces forem necessárias, sem precisar fazer gambiarras.
- Interfaces coesas são aquelas que possuem também uma única responsabilidade.
- Possibilitam maior reúso e tendem a ser mais estáveis.
- Em Domain-Driven Design (DDD), Eric Evans comenta sobre os *repositórios*, que seriam abstrações para a camada de acesso a dados.
  - Essa interface em particular nos seria bastante útil se tivéssemos a necessidade de mudar a maneira de acesso a dados.
- Interfaces são fundamentais em bons sistemas orientados a objetos. Tomar conta delas é importante.