Posts SOLID, direto ao ponto
Post
Cancel

SOLID, direto ao ponto

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.

Desktop View

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
public class Eletronico {
    public void Ligar();
}

public class Televisao : Eletronico {
    public bool suportaHDTV;
}

public class Laptop : Eletronico {
    public byte portasUSB;
}

public class SistemaIntegrado {

    public void LigarSistemas(Eletronico[] es) {
        foreach(e in es) {
            e.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.

This post is licensed under CC BY-NC-ND 4.0 by the author.