Skip to content

Reboredo.bit

Menu
  • Início
  • Sobre mim
  • Posts
Menu
solid principles

(I): Aplicando o “Princípio da Segregação da Interface” com Typescript e Java

Posted on 25 de novembro de 202526 de novembro de 2025 by victoreboredo.dev@gmail.com

Continuação do estudo sobre os princípios SOLID. Com foco na Segregação de interface.


Conceitos

SOLID é um acrônimo que representa cinco princípios fundamentais da programação orientada a objetos, propostos por Robert C. Martin – o uncle Bob. Aqui você pode ler mais sobre o artigo dele.
Esses princípios têm como objetivo melhorar a estrutura e a manutenção do código, tornando-o mais flexível, escalável e fácil de entender. Tais princípios auxiliam o programador a criar códigos mais organizados, dividindo responsabilidades, reduzindo dependências, simplificando o processo de refatoração e promovendo a reutilização do código.

O “I” do acrônimo significa “Interface Segregation Principle”. A frase que o uncle bob utilizou para definir esse princípio foi:

“Nenhum cliente deve ser forçado a depender de interfaces que não utiliza”

O Princípio da Segregação da Interface aborda um problema comum: interfaces excessivamente grandes que forçam implementações desnecessárias em classes que não precisam delas.

Aplicação prática

Imagine um sistema de autenticação em uma aplicação, onde diferentes métodos são usados para autenticar um usuário (e.g., por senha, por biometria, por QR Code).

Primeiro, vejamos a aplicação dessa classe sem utilizar o ISP em Java e Typescript:

Java

interface Authenticator {
    boolean authenticateWithPassword(String userId, String password);
    boolean authenticateWithBiometrics(String userId);
    boolean authenticateWithQRCode(String qrCode);
}

class PasswordAuthenticator implements Authenticator {
    @Override
    public boolean authenticateWithPassword(String userId, String password) {
        System.out.println("Authenticating with password...");
        return true;
    }

    @Override
    public boolean authenticateWithBiometrics(String userId) {
        throw new UnsupportedOperationException("Not implemented");
    }

    @Override
    public boolean authenticateWithQRCode(String qrCode) {
        throw new UnsupportedOperationException("Not implemented");
    }
}

Typescript

interface Authenticator {
  authenticateWithPassword(userId: string, password: string): boolean;
  authenticateWithBiometrics(userId: string): boolean;
  authenticateWithQRCode(qrCode: string): boolean;
}

class PasswordAuthenticator implements Authenticator {
  authenticateWithPassword(userId: string, password: string): boolean {
    console.log("Authenticating with password...");
    return true;
  }

  authenticateWithBiometrics(userId: string): boolean {
    throw new Error("Not implemented");
  }

  authenticateWithQRCode(qrCode: string): boolean {
    throw new Error("Not implemented");
  }
}

Problemas:

  1. Métodos não utilizados: A classe PasswordAuthenticator implementa métodos que não fazem sentido para sua função.
  2. Manutenção problemática: Se a interface mudar, todas as classes implementadoras precisam ser alteradas, mesmo que não utilizem os métodos novos.
  3. Violação de responsabilidade única: As classes começam a lidar com preocupações que não deveriam ser delas.

Para resolver o problema, podemos dividir a interface Authenticator em interfaces menores e mais específicas.

Java

interface PasswordAuth {
    boolean authenticateWithPassword(String userId, String password);
}

interface BiometricAuth {
    boolean authenticateWithBiometrics(String userId);
}

interface QRCodeAuth {
    boolean authenticateWithQRCode(String qrCode);
}

class PasswordAuthenticator implements PasswordAuth {
    @Override
    public boolean authenticateWithPassword(String userId, String password) {
        System.out.println("Authenticating with password...");
        return true;
    }
}

class BiometricAuthenticator implements BiometricAuth {
    @Override
    public boolean authenticateWithBiometrics(String userId) {
        System.out.println("Authenticating with biometrics...");
        return true;
    }
}

class QRCodeAuthenticator implements QRCodeAuth {
    @Override
    public boolean authenticateWithQRCode(String qrCode) {
        System.out.println("Authenticating with QR Code...");
        return true;
    }
}

Typescript

interface PasswordAuth {
  authenticateWithPassword(userId: string, password: string): boolean;
}

interface BiometricAuth {
  authenticateWithBiometrics(userId: string): boolean;
}

interface QRCodeAuth {
  authenticateWithQRCode(qrCode: string): boolean;
}

class PasswordAuthenticator implements PasswordAuth {
  authenticateWithPassword(userId: string, password: string): boolean {
    console.log("Authenticating with password...");
    return true;
  }
}

class BiometricAuthenticator implements BiometricAuth {
  authenticateWithBiometrics(userId: string): boolean {
    console.log("Authenticating with biometrics...");
    return true;
  }
}

class QRCodeAuthenticator implements QRCodeAuth {
  authenticateWithQRCode(qrCode: string): boolean {
    console.log("Authenticating with QR Code...");
    return true;
  }
}

Benefícios da Refatoração

  1. Interfaces específicas: Cada classe implementa apenas os métodos que realmente utiliza.
  2. Flexibilidade: Adicionar novos métodos ou modos de autenticação não impacta implementações existentes.
  3. Manutenção mais simples: Reduz o impacto de mudanças no código, evitando refatorações desnecessárias.

Conclusão

A aplicação do Princípio da Segregação de Interfaces (ISP) torna o código mais objetivo, modular e alinhado às reais necessidades de cada componente do sistema. Ao dividir interfaces grandes em unidades menores e específicas, eliminamos a obrigatoriedade de implementar métodos inúteis e reduzimos o acoplamento entre classes. Como resultado, o sistema se torna mais fácil de manter, estender e compreender — características essenciais em projetos que buscam longevidade e qualidade. Seguir o ISP não apenas melhora a arquitetura, mas também incentiva um design mais limpo e coerente com os demais princípios do SOLID.


Referências

  • Essential Software Design Principles (SOLID)
  • Systems Design: Interface
  • SOLID: I – Interface Segregation Principle (ISP)

Navegação de Post

← (L): Aplicando o “Princípio da substituição de Liskov” com Typescript e Java
(D): Aplicando o “Princípio da Inversão de Dependências” com Typescript e Java →

1 thought on “(I): Aplicando o “Princípio da Segregação da Interface” com Typescript e Java”

  1. Pingback: (D): Aplicando o “Princípio da Inversão de Dependências” com Typescript e Java - Reboredo.bit

Deixe um comentário Cancelar resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Recent Posts

  • Microsserviços: 5 Lições Aprendidas — Um Olhar Arquitetural
  • 5 Pilares financeiros que destacam negócios de alto valor
  • Princípio da Responsabilidade Única e as implicações na Orientação a Objetos e Arquitetura de Software
  • (D): Aplicando o “Princípio da Inversão de Dependências” com Typescript e Java
  • (I): Aplicando o “Princípio da Segregação da Interface” com Typescript e Java

Archives

  • novembro 2025

Categories

  • Empreendimento (1)
  • Engenharia (9)
  • Finança (2)
  • Java (6)
  • Liderança (1)
  • Orientação a Objetos (8)
  • Programação (9)
  • Programação Estruturada (2)
  • Typescript (8)
© 2025 Reboredo.bit | Powered by Minimalist Blog WordPress Theme