DEV Community

Erandir Junior
Erandir Junior

Posted on • Updated on

SOLID e o princípio da implementação desnecessária

Fala galera, chegamos ao 4º artigo sobre SOLID. E para quem não vem acompanhando ou perdeu os últimos lançamentos, já deixo aqui todos os links dos artigos anteriores, aproveitem:

Links passados, falaremos hoje sobre o Interface Segregation Principle (ISP), em português: Princípio da Segregação de Interface.

Problema

Como já é de costume, vamos ver uma historinha para entender melhor a como esse princípio pode nos ajudar.

Digamos que nós montamos uma startup. E nessa startup, configuramos um serviço de e-mail onde todos os poucos funcionários terão acesso a todos os e-mails enviados para a empresa.

Passado alguns anos, a empresa cresceu, temos muito mais funcionários, que agora estão trabalhando em setores específicos. Mesmo assim, os funcionários continuam a receber todos os e-mails enviados para a empresa. Assim, uma pessoa do setor de vendas por exemplo, visualiza e-mails que são direcionados ao setor de ti, de marketing, diretoria, etc.

Isso é um problema por alguns motivos, podemos identificar que podem haver informações sensíveis ou importantes chegando para pessoas que não deveriam, ou mesmo o acúmulo de e-mails na caixa de entrada, dificultando a identificação de um e-mail importante ou algo do tipo.

A história acima mostra claramente um problema no qual recebemos informações que simplesmente não utilizamos, deveríamos receber somente o que é necessário para nós e nada mais. Com isso em mente, veremos um problema diferente, mas que é diretamente ligado ao tema do artigo, vejam abaixo:

<?php

interface AcquisitionStep
{
    public function analyze(string content);

    public function approve();

    public function reprove();
}


class Acquisition implements AcquisitionStep
{
    public function analyze(string content)
    {
        // analyze
    }

    public function approve()
    {
        // approve
    }

    public function deny()
    {
        // deny
    }
}

class Board implements AcquisitionStep
{
    public function analyze(string content)
    {
        // analyze
    }

    public function approve()
    {
        // approve
    }

    public function deny()
    {
        // deny
    }
}
Enter fullscreen mode Exit fullscreen mode

O código acima é bem simples de entender: temos um processo de análise de um pedido de compra. Solicitamos a compra de algo para o setor de aquisição, o setor analisa, aprova ou reprova o pedido, que segue para outro passo que basicamente faz as mesmas coisas, até ser concluído o processo. Não irei me aprofundar muito no processo em si.

Até então, o processo é bem simples de entender, o problema ocorre a seguir, digamos que exista uma auditoria sobre o processo de solicitação. Em um primeiro momento podemos pensar que a auditoria é mais um passo no processo de aprovação, logo, nossa classe de auditoria implementaria a interface AcquisitionStep, como abaixo:

<?php

interface AcquisitionStep
{
    public function analyze(string content);

    public function approve();

    public function reprove();
}

class Acquisition implements AcquisitionStep
{
    public function analyze(string content)
    {
        // analyze
    }

    public function approve()
    {
        // approve
    }

    public function deny()
    {
        // deny
    }
}

class Board implements AcquisitionStep
{
    public function analyze(string content)
    {
        // analyze
    }

    public function approve()
    {
        // approve
    }

    public function deny()
    {
        // deny
    }
}

class Audit implements AcquisitionStep
{
    public function analyze(string content)
    {
        // analyze
    }

    public function approve()
    {
        // approve
    }

    public function deny()
    {
        // deny
    }
}
Enter fullscreen mode Exit fullscreen mode

Porém, temos um problema, apesar da auditoria fazer seu processo interno de análise, a mesma não aprova ou reprova uma solicitação de compra, sendo assim, nossa classe de auditoria está sendo obrigada a implementar coisas que ela simplesmente não deveria fazer.

Poderíamos lançar uma exceção caso fosse executado os métodos de aprovação ou reprovação ou deixar em branco, mas isso não é a melhor forma de resolvermos esse problema, continuamos a implementar ações que nem deveríamos fazer.

Princípio da Segregação de Interface

Primeiramente veremos a definição desse princípio:

Este princípio orienta que os projetistas de software evitem depender de coisas que não usam.

Em outras palavras, nós NÃO precisamos depender/implementar coisas da qual não usamos.

Com a explicação acima em mente, vamos refatorar nosso código respeitando o ISP, vejam abaixo:

<?php

interface AcquisitionStep
{
    public function approve();

    public function reprove(s);
}

interface Analyzer
{
    public function analyze(string content);
}

class Acquisition implements Analyzer, AcquisitionStep
{
    public function analyze(string content)
    {
        // analyze
    }

    public function approve()
    {
        // approve
    }

    public function deny()
    {
        // deny
    }
}

class Board implements Analyzer, AcquisitionStep
{
    public function analyze(string content)
    {
        // analyze
    }

    public function approve()
    {
        // approve
    }

    public function deny()
    {
        // deny
    }
}

class Audit implements Analyzer
{   
    public function analyze(string content)
    {
        // analyze
    }
}
Enter fullscreen mode Exit fullscreen mode

Quebramos nossa interface AcquisitionStep em duas, uma na qual temos os métodos de aprovação e reprovação, e outra onde somente temos o método de análise. Com isso, podemos adicionar novos passos ou mesmo novas análises, onde essas classes vão implementar somente o que é necessário para elas.

Resumo

Esse foi um artigo bem interessante de escrever, o exemplo utilizado foi algo que já presenciei, e apesar de ser bem simples, mostra claramente o problema de depender/implementar algo que não precisamos.

Não sei vocês, mas vendo o código acima me lembro do SRP, na qual as nossas classes tem apenas uma finalidade, no caso da classe Audit, ela é responsável única e exclusivamente por analisar algo. E outra coisa que consigo lembrar, é sobre o OCP, onde sabemos as entradas e saídas, mas não sabemos o comportamento interno, assim criamos uma certa padronização no código.

Espero que tenham gostado do conteúdo. Por hoje é só, aguardo vocês no próximo, até logo.

Latest comments (0)