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:
- SOLID e o princípio do não faça mais do que não deve
- SOLID e o princípio do faça algo, mas do seu jeito
- SOLID e o princípio do 6 por meia dúzia
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
}
}
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
}
}
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
}
}
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.
Top comments (0)