13 de novembro de 2016



O princípio da segregação da interface também conhecido pela sigla ISP é abordado no livro de Martin (2006), ele diz que interfaces específicas são melhores que uma interface geral. A falta a esse princípio pode levar algumas classes a obterem conhecimento de métodos que elas não necessariamente vão utilizar. Isso acontece porque se o código possuir uma única interface geral, as implementações daquela interface conhecerão todos os métodos ali disponíveis mesmo que devam implementar somente alguns. É interessante que em um código, uma classe que implemente uma interface tenha disponível nela somente os métodos que deverá utilizar para evitar sua poluição com a implementação de métodos desnecessários.

Considere por exemplo, um sistema que controla a abertura e fechamento de portas:


public class Porta {
    public void fecha( ){ … }
    public void abre( ) { … }
    public boolean portaAberta( ) { … }
}

As portas de cofre devem ser abertas somente em determinados horários:

public classe PortaCofre extends Porta {
    public void defineHorario ( ){ … }
    public boolean podeAbrir( ) { … }
}

As Portas são utilizadas no sistema como um todo:

public class Predio {
private Porta[ ] porta; …
}

O sistema funciona de forma conveniente, mas, seria interessante acrescentar a possibilidade de que seja disparado um alarme caso as portas de cofre fiquem abertas após um limite de tempo. O sistema já possui uma classe Temporizador implementada, é necessário utilizá-la com o mínimo de alteração no sistema. O Temporizador tem um tempo específico para disparar o alarme:

public class Temporizador {
    public void registra (int t,Monitorado c){ … }
}

public class Monitorado {
    public disparaAlarme( ){ ... }
}

Conforme veremos na implementação a seguir, a classe Porta estenderá a classe Monitorado. O problema dessa nova implementação é que a classe Porta terá acesso ao método disparaAlarme sem necessidade, uma vez que somente a classe PortaCofre fará o uso do método. A presença de disparaAlarme em Porta polui sua interface.

public class Porta extends Monitorado{
    public void fecha( ){ … }
    public void abre( ) { … }
    public boolean portaAberta( ) { … }
   
// Aqui o ISP foi ferido   
public void disparaAlarme() { }
}
public classe PortaCofre extends Porta {
    public void disparaAlarme ( ){ … }
    public void defineHorario ( ){ … }
    public boolean podeAbrir( ) { … }
}
Solução do problema:

public class Temporizador {
public void registra (int t, Monitorado c);{ …}
}
public interface Monitorado {
public disparaAlarme( )
}

public class Porta {
    public void fecha( ){ … }
    public void abre( ) { … }
    public boolean portaAberta( ) { … }
}

public class PortaCofre extends Porta
              implements Monitorado {
    public void defineHorario ( ){ … }
    public boolean podeAbrir( ) { … }
    public void disparaAlarme( ) { … }
}

Agora o ISP passou a ser respeitado, uma vez que as classes estão implementando somente os métodos que realmente irão utilizar. A classe Monitorado passou a ser uma interface e PortaCofre agora implementa essa interface além de estender Porta. Assim, foi eliminada a poluição causada com o problema da implementação, pois, Porta não precisa mais ter acesso ao método disparaAlarme. As classes não terão que incorporar métodos que não precisam utilizar e o aplicativo fica mais organizado e fácil de entender.

Referência:

MARTIN, R.C.; MARTIN, M. Agile Principles, Patterns, and Practices in C#. 1. ed. New Jersey: Prentice Hall, 2006.

0 comentários:

Postar um comentário

Comentários:

Perfil

Formada em Sistemas de Informação e pós-graduada em Engenharia de Software.

Facebook

Views