PRINCÍPIO DA SEGREGAÇÃO DE INTERFACES

dev.to

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?

Source: dev.to

arrow_back Back to News