Depois de um longo hiato, estou retomando a série dos príncipios SOLID, trazendo o quarto dos princípios.
Interface Segregation Principle
(Princípio da Segregação de Interface)
Uma classe não deve ser forçada a implementar interfaces que não irá utilizar.
Abstração é o coração da orientação a objetos. Em PHP, nós conseguimos alcançar um nível de abstração utilizando interfaces e classes abstratas.
Mas, antes, vamos dar um passo atrás: o que é interface?
Interface é um conjuntos de abstrações que todas as classes que a implementam deve seguir. Cada método adicionado na interface é uma assinatura, e a partir do momento que uma classe a implementa, esta fica obrigada a adicionar todas as assinaturas previamente criadas na interface.
Partindo deste princípio, parece óbvio que uma classe não deva ser forçada a implementar algo que não irá usar. Mas nesse artigo, você verá que este princípio é muito fácil de violar.
Seguindo o nosso exemplo de Employees e Contractors, até o terceiro post da série eu criei uma classe chamada UserService
que injeta os repositories para os dois tipos de usuário.
Vamos fazer uma pequena alteração, a partir de agora será um service para cada tipo de usuário.
class EmployeeService
{
protected $employeeRepository;
public function __construct(EmployeeRepository $employeeRepository)
{
$this->userRepository = $userRepository;
}
}
class ContractorService
{
protected $contractorRepository;
public function __construct(ContractorRepository $contractorRepository)
{
$this->contractorRepository = $contractorRepository;
}
}
Dessa maneira eu terei duas classes que irão implementar a mesma interface UserInterface
.
interface UserInterface
{
public function register(array $attributes, UserRepository $userRepository);
public function calcWorkedHours(array $hours);
}
Interface criada com a assinatura do método register
(que foi criado nos posts anteriores), e agora adicionei o método calcWorkedHours
que será um método útil para o usuário do tipo Contractor onde as horas dele serão calculadas para gerar o pagamento no fim do mês.
Vamos implementar a interface nos dois services.
class EmployeeService implements UserInterface
{
public function register(array $attributes, UserRepository $userRepository)
{
// implementação do código
}
}
class ContractorService implements UserInterface
{
public function register(array $attributes, UserRepository $userRepository)
{
// implementação do código
}
public function calcWorkedHours(array $hours)
{
// implementação do código
}
}
Dessa maneira nós vamos ter um erro na classe EmployeeService
pois ela implementa a UserInterface
mas não usa o método calcWorkedHours
.
Uma maneira errada de resolver isso seria implementar o método, mas sem nenhuma implementação dentro do escopo.
A maneira correta seria criar duas interfaces e implementá-las onde for necessário.
interface UserInterface
{
public function register(array $attributes, UserRepository $userRepository);
}
interface ContractorInterface
{
public function calcWorkedHours(array $hours);
}
E após criar as duas interfaces, as classes já poderiam escolher quem implementar.
class EmployeeService implements UserInterface
{
public function register(array $attributes, UserRepository $userRepository)
{
// implementação do código
}
}
class ContractorService implements UserInterface, ContractorInterface
{
public function register(array $attributes, UserRepository $userRepository)
{
// implementação do código
}
public function calcWorkedHours(array $hours)
{
// implementação do código
}
}
Dessa maneira, não obrigamos nenhuma classe a implementar algo que não irá utilizar. Sendo assim, não violamos o princípio da segregação de interface. :)
Quando tentamos entender apenas a teoria dos princípios, parecem bem mais complicados do que realmente são.
No próximo, e último, artigo da série vou falar sobre o Dependency Inversion Principle (Princípio da Inversão de Dependência).
Dúvidas e feedbacks são sempre bem-vindos.
Latest comments (7)
Parabéns Lucas, conteúdo TOP 1, nas minhas pesquisas e cursos que comprei nenhum teve uma didática tão assertiva que me fez entende os conceitos de uma forma bem mais tranquila.
Estou ansiosa pelo próximo item da série, gostei muito.
Demorou, mas saiu! :)
dev.to/lucascavalcante/principios-...
Oi Lucas, nao deixe de postar o 5 item da serie, gostei muito das suas explicações. Abraço
Agora em Janeiro sai. 😎
Aguardando! hehehe
Hahahaha, demorou mas saiu: dev.to/lucascavalcante/principios-...