C# - Princípio Da Segregação da Interface(ISP)


Hoje é dia de SOLID. Veremos o princípio da Segregação da Interface (ISP).

O princípio de segregação de interface (ISP) afirma que:

"nenhum cliente deve ser forçado a depender dos métodos que não usa."

O ISP divide as interfaces muito grandes em menores e mais específicas, para que os clientes precisem apenas conhecer os métodos que lhes interessam.

O ISP tem como objetivo manter um sistema dissociado e, portanto, mais fácil de refatorar, alterar e reimplementar, ele é um dos cinco princípios SOLID semelhante ao Princípio de Alta Coesão do GRASP.

Nota: GRASP significa General Responsibility Assignment Software Patterns (ou principles), e consiste em diretrizes para atribuir responsabilidade a classes e objetos em projeto orientado a objetos.

Este princípio afirma que os clientes não devem ser forçados a depender das interfaces que eles não usam. Quando temos interfaces não coesas, o ISP nos orienta a criar múltiplas interfaces menores e coesas.

Nota: Coesão é o nível de integralidade interna de uma classe e mede o grau em que uma classe ou seus métodos fazem sentido, ou seja, quão claro é o entendimento do que a classe ou método possui. Uma alta coesão indica responsabilidades bem definidas.

Quando você aplica o ISP, a classe e suas dependências se comunicam usando interfaces fortemente focadas, minimizando as dependências de membros não utilizados e reduzindo o acoplamento de acordo.

Interfaces menores são mais fáceis de implementar, melhorando a flexibilidade e a possibilidade de reutilização. Como menos classes compartilham interfaces, o número de alterações necessárias em resposta a uma modificação da interface é reduzido, e, isso aumenta a robustez.

Veja o exemplo de código a seguir:

    public interface IPedido
    {
        void Compra();
        void ProcessarCartaoCredito();
    }
    public class PedidoOnline : IPedido
    {
        public void Compra()
        {
            //código da compra
        }
        public void ProcessarCartaoCredito()
        {
            //processo do cartão
        }
    }
    public class PedidoPresencial : IPedido
    {
        public void Compra()
        {
            //código da compra
        }
        public void ProcessarCartaoCredito()
        {
            //Não precisa para boleto
            throw new NotImplementedException();
        }
    }

Neste código temos a interface IPedido sendo implementada pelas classes PedidoOnline e PedidoPresencial.

Aparentemente tudo esta correto e o código vai funcionar.

Mas este código esta violando o princípio ISP pois a interface IPedido esta sendo implementada pela classe PedidoPresencial mas esta classe não esta implementando o método ProcessarCartaoCredito.

Assim a classe esta sendo forçada a depender do método ProcessarCartaoCredito que ela não precisa usar.

Para adequar o código ao princípio ISP podemos fazer assim:

  class ISP
    {
        public interface IPedido
        {
            void Compra();
        }
        public interface IPagamentoCartao
        {
            void ProcessarCartaoCredito();
        }
        public class PedidoOnline : IPedido, IPagamentoCartao
        {
            public void Compra()
            {
                //compra
            }
            public void ProcessarCartaoCredito()
            {
                //processa cartão
            }
        }
        public class PedidoPresencial : IPedido
        {
            public void Compra()
            {
                //compra
            }
        }
    }

Agora temos interfaces específicas IPedido e IPagamentoCartao, e, nenhuma classe esta sendo obrigada a implementa um método que não utiliza.

E estamos conversados...

"Não se turbe o vosso coração; credes em Deus, crede também em mim.
Na casa de meu Pai há muitas moradas; se não fosse assim, eu vo-lo teria dito. Vou preparar-vos lugar."

João 14:1,2


Referências:


José Carlos Macoratti