Continuando a série sobre os princípios SOLID, chegamos ao quarto princípio, conhecido por Princípio da Segregação de Interface (Interface Segregation Principle), ou simplesmente ISP.
DEFINIÇÃO
O Princípio da Segregação de Interface trata da coesão de interfaces e diz que clientes não devem ser forçados a depender de métodos que não usam.
EXEMPLO DE VIOLAÇÃO
Vejamos a seguinte interface:
E agora temos as classes Dev, ScrumMaster e ProductOwner implementando a interface MembroDeTimeScrum:
Ao criarmos uma interface genérica demais, acabamos fazendo com que uma implementação, no caso Dev, não utilize certos métodos da interface. É o que acontece com os métodos PriorizarBacklog e BlindarTime, que não fazem nada, pois não são atribuições de um Dev e sim do ProductOwner e do ScrumMaster, respectivamente.
PROBLEMAS
Suponhamos que alguma alteração seja necessária no método BlindarTime, que agora precisa receber alguns parâmetros. Dessa forma, somos obrigados a alterar todas implementações de MembroDeTimeScrum – Dev, ScrumMaster e ProductOwner – por causa de uma mudança que deveria afetar apenas a classe ScrumMaster.
Além disso, classes-cliente que dependiam de MembroDeTimeScrum terão que ser recompiladas e se estão em diversos componentes terão que ser redistribuídas. Algumas vezes desnecessariamente, pois nem sequer faziam uso do método BlindarTime!
Outro problema é que a implementação de métodos inúteis (chamados “degenerados”) pode levar à violação do LSP, pois alguém utilizando MembroDeTimeScrum poderia supor o seguinte:
No entanto, sabemos que apenas Dev executa o comportamento acima. Se a lista tivesse também objetos do tipo ScrumMaster ou ProductOwner, esses objetos não estariam realizando nada, ou pior, poderiam disparar alguma exceção, caso a implementação dos mesmos assim o fizesse.
RESOLVENDO A VIOLAÇÃO DO ISP
A solução para o exemplo acima seria criamos interfaces mais específicas para que cada classe cliente dependa apenas do que realmente necessita. Por exemplo:
Com a alteração acima, a classe concreta ScrumMaster não precisa mais implementar métodos desnecessários e demais classes que dependiam de MembroDeTimeScrum apenas para utilizar BlindarTime podem agora depender da interface FuncaoDeScrumMaster.
A mesma ideia pode ser aplicada para as funções específicas de Dev e ProductOwner. Assim todos os clientes de MembroDeTimeScrum agora podem depender especificamente das interfaces que utilizam.
CONCLUSÃO
O Princípio da Segregação de Interface nos alerta quanto à dependência em relação a “interfaces gordas”, forçando que classes concretas implementem métodos desnecessários e causando um acoplamento grande entre todos os clientes.
Ao usarmos interfaces mais específicas, quebramos esse acoplamento entre as classes clientes, além de deixarmos as implementações mais limpas e coesas.
Comments