Logo

dev-resources.site

for different kinds of informations.

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

Published at
1/13/2025
Categories
interfacesegregation
solidprinciples
designpatterns
softwaredevelopment
Author
thrsouza
Author
8 person written this
thrsouza
open
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.

Como de costume: Calma e respira... Está tudo bem!

Vamos seguir com os exemplos e, caso não tenha entendido, eu garanto que você vai sair desta página totalmente esclarecido.

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 você pode imaginar. Acho complicado e triste falar sobre isso mas, em mais de dez anos de carreira, testemunhei este tipo de abordagem muitas e muitas vezes...

Image description

Não sou hipócrita e muito menos um santo para dizer que nunca fiz nada parecido. Afinal, ninguém chega no mundo da programação com todas as boas práticas e princípios decorados prontos para serem executados. Não é mesmo?

Tudo isso faz parte do processo de crescimento de todo bom desenvolvedor e arquiteto de software.

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

Como eu disse, é muito simples. Lançar exceções ou implementar métodos vazios simplesmente porque a classe X não consegue atender ao comportamento da interface Y não é uma boa prática. Pense sempre na coerência, durabilidade e longevidade do seu código.


Espero que você tenha compreendido a mensagem e que este artigo tenha sido realmente útil e esclarecedor para você.

Me siga para receber mais conteúdos como este. ❤️


Recomendação de leitura:
Arquitetura Limpa - O Guia do Artesão para Estrutura e Design de Software
Robert Cecil Martin, 2019.

designpatterns Article's
30 articles in total
Favicon
ISP - O Princípio da Segregação de Interface
Favicon
7 Essential Design Patterns for JavaScript Developers: Boost Your Coding Mastery
Favicon
Usando Strategy Pattern para evitar condicionamento exagerado
Favicon
Singleton ou Observable? A Escolha Errada Pode Custar Sua Promoção!
Favicon
Disadvantages of the Single Responsibility Principle(SRP)
Favicon
Color Theory in UI Design
Favicon
Builder Pattern in C#: Practical Implementation and Examples
Favicon
[Boost]
Favicon
Cloud Design Patterns 01-10
Favicon
Observer Design Pattern | Low Level Design
Favicon
Foundations of Interior Design: Mastering the Art with the Best Interior Design Courses in Bangalore
Favicon
GRASP Pattern - Nguyên Tắc Thiết Kế Trách Nhiệm Hướng Đối Tượng
Favicon
🌟 Exciting Update: LivinGrimoire Wiki Revamp! 🌟
Favicon
Giới Thiệu Về Pattern Trong Phát Triển Phần Mềm
Favicon
Giới Thiệu Về Pattern Trong Phát Triển Phần Mềm
Favicon
Fallback Pattern in .NET Core: Handling Service Failures Gracefully
Favicon
Learn Design Patterns: Understanding the Adapter Pattern for Compatibility
Favicon
Top 10 Design Patterns for Programming Interviews
Favicon
Handling NullPointerException with Optional
Favicon
SOLID: Dependency Inversion Principle (DIP) in C#
Favicon
Introducing TheShell: A Game-Changer in LivinGrimoire
Favicon
O que é o hikari pool?
Favicon
Concurrency Patterns: Balking Pattern
Favicon
Observer Design Pattern O'zbek tilida
Favicon
Memento Design Pattern O'zbek tilida
Favicon
Command design pattern 🥷 O'zbek tilida
Favicon
Mediator design pattern O'zbek tilida
Favicon
Concurrency Patterns: Active Object
Favicon
Learn Design Patterns: Understanding the Factory Method Pattern
Favicon
Understanding the State Pattern

Featured ones: