DEV Community

Cover image for PRINCÍPIO DA SEGREGAÇÃO DE INTERFACES
Victor Lis Bronzo
Victor Lis Bronzo

Posted on

PRINCÍPIO DA SEGREGAÇÃO DE INTERFACES

Nenhuma classe deve ser dependente de métodos que não precisa.

Um exemplo seria uma interface “Máquina”, que força os métodos print( ), scan( ) e fax( ). Nem toda máquina tem esses 3 métodos.

Então criamos as interfaces IPrinter, IScanner e IFax. Agora uma máquina assina apenas os contratos que realmente precisa e cumpre apenas esses.

Exemplo de Código (Opcional - Ilustrando o texto):

// ❌ Anti-pattern: Interface genérica forçando métodos não utilizados
interface IMaquina {
  print(): void;
  scan(): void;
  fax(): void;
}

// ✅ SOLID: Interfaces segregadas e específicas
interface IPrinter { print(): void; }
interface IScanner { scan(): void; }
interface IFax { fax(): void; }
Enter fullscreen mode Exit fullscreen mode

A DEFINIÇÃO

Na prática, podemos entender o ISP como o conceito de que uma classe nunca deve depender de métodos que não utiliza.

A interface deve ser reutilizável em vários casos, logo uma interface engessada e com métodos em excesso atrapalha nesse processo.

Quando uma classe assina um contrato gigante, ela é obrigada a implementar métodos que não fazem sentido para o contexto dela, sujando o código e gerando acoplamento desnecessário.


UM MAU EXEMPLO

Contexto: Um sistema de blog onde todo user assina o mesmo contrato.

Aqui ferimos alguns conceitos que citei.

Exemplo de Código:

// RUIM: Interface obesa. Força comportamentos desnecessários.
interface IUserActions {
  readPost(): void;
  writePost(): void;
  banUser(): void; // Usuário comum não deveria ver isso!
}

class StandardUser implements IUserActions {
  public readPost(): void { console.log("Lendo..."); }
  public writePost(): void { console.log("Escrevendo..."); }

  // ERRO: O usuário comum é forçado a ter esse método
  public banUser(): void {
    throw new Error("Acesso Negado: Você não é administrador.");
  }
}
Enter fullscreen mode Exit fullscreen mode

DIVIDIR PARA CONQUISTAR

A solução no ponto de vista do ISP é clara, quebrar essa interface enorme em pequenos contratos bem escopados.

Quando for necessário mais de um contrato, pode ser construído um novo contrato com essa combinação específica ou o próprio assinante assumir mais de um contrato por vez (a depender da linguagem).


UM BOM EXEMPLO

Mesmo contexto, mas com escopos bem mais definidos.

Como é possível observar, apenas o necessário é assinado.

Exemplo de Código:

// BOM: Interfaces pequenas e específicas.
interface IReader { readPost(): void; }
interface IWriter { writePost(): void; }
interface IAdmin { banUser(): void; }

// O usuário comum implementa apenas o que ele realmente faz
class StandardUser implements IReader, IWriter {
  public readPost(): void { console.log("Lendo..."); }
  public writePost(): void { console.log("Escrevendo..."); }
}

// O Admin assina todos os contratos
class AdminUser implements IReader, IWriter, IAdmin {
  public readPost(): void { console.log("Lendo..."); }
  public writePost(): void { console.log("Escrevendo..."); }
  public banUser(): void { console.log("Usuário banido!"); }
}
Enter fullscreen mode Exit fullscreen mode

A LONGO PRAZO

Segregar interfaces deixa o seu código altamente modular. Se amanhã as regras de banimento de um IAdmin mudarem, a classe StandardUser não precisará ser tocada ou recompilada.

O seu sistema passa a ser construído como blocos de Lego, encaixando apenas as peças (contratos) que fazem sentido para aquela estrutura.


Meus Links
Github: victor-lis-bronzo
Linkedin: victor-lis-bronzo
Portfólio: portfolio.victorlisbronzo.me
Portfólio mais legal: victorlisbronzo.me


Deixe sua reação ❤️
Você tem o costume de criar várias interfaces pequenas ou acaba criando uma só para tudo?

Top comments (0)