Interface Segregation Principle
O ISP afirma que uma interface não deve forçar a classe a implementar métodos que elas não utilizam. A ideia é quebras grandes interfaces em menores e mais específicas, ou seja, em vez de interfaces gigantes e genéricas (”interfaces gordas”), devemos ter “interfaces magras”, quebradas e mais específicas.
“Clientes não devem ser forçados a depender de métodos que não usam.”
Pense nisso como um menu de restaurante:
- Violação do ISP: O restaurante obriga você a comprar o combo com hambúrguer, batata, refrigerante, sorvete e café, mesmo que você só queira o hambúrguer
- Aplicação do ISP: O menu é segregado. Você pode pedir itens individuais ou combos menores que façam sentido para o seu "apetite" (necessidade)
Exemplo didático do problema
Imagine que temos a Interface chamada ITrabalhador, ela possui métodos como Codificar(), Testar() e GerenciarProjetos().
- Você vai criar uma classe chamada
Programadorque implementa essa interface. Até esse cenário tudo ocorre como o esperado. - O problema é que se você criar uma classe
Gerente, e implementar a mesma interface ela será obrigada a implementarCodificar(), mesmo que o gerente não escreva código.
Essa prática cria um acoplamento desnecessário e “polui” o código com métodos vazios ou que lançam exceções como throw new NotImplementedException.
Exemplo técnico do problema
Vamos retomar o exemplo acima e desenvolver com o código com C# de duas formas, uma que viola o ISP e outra que não viola.
1. Violação estrutural
using System;
// Uma "Interface Gorda" que tenta fazer tudo
public interface ITrabalhador
{
void Codificar();
void Testar();
void GerenciarProjeto();
}
public class Programador : ITrabalhador
{
public void Codificar() => Console.WriteLine("Escrevendo código C#...");
public void Testar() => Console.WriteLine("Testando bugs...");
public void GerenciarProjeto() => Console.WriteLine("Atualizando o JIRA...");
// Ok, talvez o programador faça um pouco de tudo.
}
public class Gerente : ITrabalhador
{
public void Codificar()
{
// Oxente! O Gerente não deveria ser obrigado a ter este método.
throw new NotImplementedException("Gerentes não codificam!");
}
public void Testar()
{
throw new NotImplementedException("Gerentes não testam!");
}
public void GerenciarProjeto() => Console.WriteLine("Gerenciando o time...");
}
2. O Jeito Correto
Agora, vamos segregar (separar) as interfaces. Assim, cada classe só assina o "contrato" que realmente consegue cumprir.
// Interfaces segregadas e específicas (Interfaces Magras)
public interface ICodificador
{
void Codificar();
}
public interface ITestador
{
void Testar();
}
public interface IGerente
{
void GerenciarProjeto();
}
// O Programador implementa apenas o que faz sentido para ele
// Ele pode implementar múltiplas interfaces se necessário!
public class Programador : ICodificador, ITestador
{
public void Codificar() => Console.WriteLine("Escrevendo código C#...");
public void Testar() => Console.WriteLine("Testando bugs...");
}
// O Gerente agora está limpo e focado
public class Gerente : IGerente
{
public void GerenciarProjeto() => Console.WriteLine("Gerenciando o time...");
}
Top comments (0)