A saga de “direto ao ponto” apresenta alguns textos rápidos para desmistificar assuntos simples.
S O L I D
Ao trabalhar efetivamente com Programação Orientada a Objetos (POO), provavelmente os 5 princípios SOLID já estão presentes no dia a dia, mesmo que de forma não intencional.
S — Single Responsiblity Principle
(Princípio da responsabilidade única)
Ao separar a arquitetura do projeto em camadas, provavelmente as suas classes já são quebradas, mantendo-as com uma responsabilidade única.
O — Open-Closed Principle.
(Princípio Aberto-Fechado)
As classes devem estar abertas para extensão, mas fechadas para modificação. Uma forma simples de implementar, é definir as ações do sistema em interfaces e referencie-as nas funções ao invés de trabalhar com as classes originais.
Exemplificando, considere Enumerable
uma interface para utilizar na função de Count()
que avança para a função Next()
até acabar a lista. Em nenhum momento um array de um objeto foi citado, e a função Count()
trabalha exclusivamente com a interface.
1
2
3
4
5
6
public int Count(Enumerable e){
int i = 0;
do {
i++;
} while(e.Next());
}
L — Liskov Substitution Principle.
(Princípio da substituição de Liskov)
Quando uma classe estende outra, trabalhe a classe de mais alto nível nas funções. Assim sendo, se existir a classe Eletronico
, e as classes filhas Televisão
e Laptop
, sempre dê preferência por trabalhar funções que manipulam Eletronico
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public abstract class Eletronico
{
public bool ON;
public virtual void Ligar() {
ON = true;
}
}
public class Televisao : Eletronico
{
public bool suportaHDTV;
public override void Ligar()
{
base.Ligar();
if (suportaHDTV){
//tenta conectar antena
}
}
}
public class Laptop : Eletronico
{
public byte portasUSB;
}
public class SistemaIntegrado
{
Televisao televisao;
Laptop laptop;
public SistemaIntegrado()
{
televisao = new Televisao() { suportaHDTV = true };
laptop = new Laptop() { portasUSB = 2 };
}
public void LigarSistemas()
{
televisao.Ligar();
laptop.Ligar();
}
}
I — Interface Segregation Principle.
(Princípio da Segregação da Interface)
Não obrigue uma classe importar uma interface, se a mesma não for implementar todo o contrato.
Considere duas classes, ContaCorrente
e ContaPoupanca
, onde ambas podem receber depósitos e recebem a implementação da interface Depositavel
. Caso seja necessário rentabilizar o dinheiro da ContaPoupanca
, não adicione a função CalcularLucro
na mesma interface, afinal, a classe ContaCorrente
não irá implementar tal calculo. Crie uma interface Rentavel
e atribua apenas nos tipos de conta que terão rentabilidade.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public interface Depositavel {
public function Depositar(int valor);
}
public interface Rentavel {
public void CalcularLucro();
}
public class ContaCorrente : Depositavel {
public void Depositar(int valor) {
// depositar em conta corrente
}
}
public class ContaPoupanca : Rentavel, Depositavel {
public void CalcularLucro() {
// calculo base da poupanca
}
public void Depositar(int valor) {
// depositar em conta poupanca
}
}
D — Dependency Inversion Principle.
(Princípio da Inversão de Dependência)
Encapsule qualquer classe externa dentro de uma classe própria, e passe este objeto para as classes que irão utilizar. Um injetor de dependência já garante a inversão de dependência.
Por exemplo, não deixe a função EnviarEmail
responsável por decidir como obter o Remente
, e em vez disso, já receba pronto as instâncias necessárias.
1
2
3
public bool EnviarEmail(Remetente r, Destinatario d, Formatador f, EmailManager em) {
return em.Send(r.All(), d.All(), f.ToEmailEncode());
}
Por hoje é só pessoal!
Continue a acompanhar as próximas publicações para abordarmos mais temas de forma descomplicada e direto ao ponto.