SOLID Ruby: Liskov Substitution Principle e Interface Segregation Principle

Por Lucas Húngaro*

Para fechar os cinco princípios do SOLID, vamos falar sobre os dois princípios restantes: Liskov Substitution Principle (LSP) e Interface Segregation Principle (ISP).

Como já foi falado anteriormente, esses princípios foram formulados com linguagens estáticas em mente e, por essa razão, precisam ser “adaptados” para que sejam aplicados em linguagens dinâmicas. Note que, em suas formas originais, esses princípios em geral recorrem a técnicas como herança para contornar as “amarras” do sistema estático de tipos.

No caso do LSP temos mais um exemplo disso. Em sua forma original ele é definido da seguinte forma:

If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2, then S is a subtype of T.

O que foi “traduzido” para o OOP da seguinte forma:

Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.

Em Ruby isso não é muito problemático pois, como sabemos, não estamos presos à tipos. O importante, como já vimos com o OCP, é manter a mesma interface, de forma que se precisarmos modificar alguma entidade, as demais entidades que dela dependem não precisem ser modificadas.

Além da interface, também precisamos prestar atenção ao comportamento. Modificações no comportamento podem fazer com que clientes da entidade sofram consequências inesperadas.

Já o ISP é definido da seguinte forma:

Clients should not be forced to depend upon interfaces that they do not use.

Isso quer dizer que um cliente (entidade que depende de alguma outra) não deve depender de interfaces não utilizadas por ele pois, em caso de modificação nessa interface, mesmo que o cliente em questão não a utilize, também terá que ser modificado.

Em linguagens estáticas há uma série de técnicas e artifícios para atingir isso. Em Ruby, o Duck Typing nos entrega esse princípio “de graça”, já que cada entidade depende apenas da interface que utiliza, independente do restante (e de tipos). Apesar disso, devemos sempre buscar entidades com interfaces coesas e bem delimitadas, evitando que sejam muito extensas e genéricas (o SRP se aplica aqui também). Aplicar o design pattern Adapter é uma boa forma de respeitar isso.

Bem, é fácil perceber que os últimos três princípios discutidos (OCP, LSP e ISP) lidam diretamente com formas de garantir interfaces estáveis para atingirmos o nosso objetivo de evitar que mudanças no código gerem um “efeito dominó” e façam com que tenhamos que alterar várias partes do software.

Mas, já que não temos estruturas como Interfaces e classes abstratas para garantir que estamos respeitando a interface definida, como garantir a aplicação desses princípios? Bom, há algumas formas para fazer isso. Aprenda a “emular” uma interface e pesquisar outros materiais recomendados em:

http://blog.lucashungaro.com/2011/05/18/solid-ruby-liskov-substitution-principle-e-interface-segregation-principle/

*Lucas Húngaro é desenvolvedor da equipe de Ruby da Gonow.

Categorias:

Gonow

O blog Gonow Tecnologia é voltado para publicação de notícias sobre eventos e temas relacionados ao mercado de Tecnologia de Informação e Comunicação (TIC), Design e User Experience (UX), além de rico conteúdo técnico - incluindo ví­deos na íntegra de palestras sobre os assuntos divulgados - e referências sobre as mais diversas linguagens de programação, frameworks e plataformas de desenvolvimento.

Veja todos os posts de "Gonow"

Comments are closed.