DEV Community

Ð̸aniel ₿elintani
Ð̸aniel ₿elintani

Posted on

SOLID, direto ao ponto

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.

public int Count(Enumerable e){
    int i = 0;
    do {
        i++;
    } while(e.Next());
}
Enter fullscreen mode Exit fullscreen mode

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.

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();
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

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.

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
    }
}

Enter fullscreen mode Exit fullscreen mode

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.

public bool EnviarEmail(Remetente r, Destinatario d, Formatador f, EmailManager em) {
    return em.Send(r.All(), d.All(), f.ToEmailEncode());
}
Enter fullscreen mode Exit fullscreen mode

Por hoje é só pessoal!

Continue a acompanhar as próximas publicações para abordarmos mais temas de forma descomplicada e direto ao ponto.

Top comments (0)