DEV Community

Cover image for ISP - O Princípio da Segregação de Interface
Thiago Souza
Thiago Souza

Posted on • Edited on

ISP - O Princípio da Segregação de Interface

O ISP (Interface Segregation Principle) foi formulado e utilizado pela primera vez por Robert C. Martin (o famoso Uncle Bob), enquanto ele realizava uma consultoria para a Xerox.

Este princípio, na minha opnião, é o mais simples dos 5 Princípios SOLID e, ao mesmo tempo, o mais negligenciado dentre os desenvolvedores e arquitetos de software. No entanto, isso depende muito da linguagem de programação utilizada.

Linguagens dinamicamente tipadas, como o Python por exemplo, não forçam qualquer tipo de implementação. Isso acontece devido ao fato de as declarações serem inferidas em tempo de execução.

Definição do ISP

Não trouxe nenhuma frase bonita escrita (ou dita) por alguma estrela da arquitetura de software, mas podemos definir e afirmar que:

A segregação de interface deve ser realizada sempre que um tipo/classe estiver sendo forçado a implementar um atributo e/ou um comportamento sem sentido e/ou sem propósito.

Vamos aos exemplos; se algo não estiver claro, a seção de aplicação consolida a ideia.

Violação do ISP

Podemos imaginar um cenário simples onde temos uma interface IPrinter que possui dois métodos: Print e Scan. Nosso programa possui duas classes que implementam essa interface, denominadas AdvancedPrinter e BasicPrinter.

A classe AdvancedPrinter pode imprimir e escanear documentos, e por isso implementa ambos os métodos. Já a classe BasicPrinter pode apenas imprimir documentos, portanto implementa apenas o método Print e lança uma exceção caso o método Scan seja acionado. Segue o código com este exemplo:

public record Document(string Name, string Content);

public interface IPrinter
{
    void Print(Document document);

    Document Scan();
}

public class AdvancedPrinter : IPrinter
{
    public void Print(Document) 
    {
        // Lógica para impressão do documento.
    }

    public Document Scan()
    {
        // Lógica para escanear um documento.
    }
}

public class BasicPrinter : IPrinter
{
    public void Print(Document) 
    {
        // Lógica para impressão do documento.
    }

    public Document Scan()
    {
        throw new NotImplementedException(
            "Esta impressora não pode escanear documentos.");
    }
}
Enter fullscreen mode Exit fullscreen mode

Situações como esta são mais comuns do que parece e, em geral, indicam oportunidades de melhorar coesão e reduzir acoplamento.

Faz parte da evolução do time identificar esses casos e substituí-los por um desenho mais aderente ao domínio.

Mas se você ainda tem dúvidas do que deveria ser feito neste caso, não se preocupe! Este artigo foi escrito com muito carinho para ajudar pessoas como você! Pessoas que têm o brilho nos olhos e o interesse em construir códigos de qualidade.

Aplicação do ISP

Para ficar em conformidade com o Princípio da Segregação de Interface e resolver este problema é realmente muito simples!

Seguindo uma abordagem similar à utilizada no artigo sobre LSP, precisamos separar os comportamentos em interfaces distintas e implementá-las apenas quando forem realmente necessárias.

Sendo assim, podemos corrigir o exemplo apresentado há pouco da seguinte forma:

public record Document(string Name, string Content);

public interface IPrinter // Possui apenas o método de impressão.
{
    void Print(Document document);
}

public interface IScanner // Possui apenas o método de escaneamento.
{
    Document Scan();
}

public class AdvancedPrinter 
    : IPrinter, IScanner // Implementa ambas as interfaces.
{
    public void Print(Document) 
    {
        // Lógica para impressão do documento.
    }

    public Document Scan()
    {
        // Lógica para escanear um documento.
    }
}

public class BasicPrinter 
    : IPrinter // Implementa apenas a interface com método de impressão.
{
    public void Print(Document) 
    {
        // Lógica para impressão do documento.
    }
}
Enter fullscreen mode Exit fullscreen mode

A abordagem é direta: lançar exceções ou criar métodos vazios apenas para cumprir uma interface é um antipadrão. Priorize coerência, durabilidade e longevidade do código.


Obrigado pela leitura.
Para aprofundar: Arquitetura Limpa — O Guia do Artesão para Estrutura e Design de Software (Robert C. Martin, 2019).

Top comments (0)