SOLID e o princípio da implementação desnecessária
Tags: oop, programming, solid, isp
Published: 2021-08-23 14:56:46

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**](https://dev.to/erandirjunior/solid-e-o-principio-do-nao-faca-mais-do-que-nao-deve-5g2b)
* [**SOLID e o princípio do faça algo, mas do seu jeito**](https://dev.to/erandirjunior/solid-e-o-principio-do-faca-algo-mas-do-seu-jeito-1gkb)
* [**SOLID e o princípio do 6 por meia dúzia**](https://dev.to/erandirjunior/solid-e-o-principio-do-6-por-meia-duzia-2h8h)

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
<?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
<?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
<?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.