SOLID , Shazam da orientação a objetos? — Parte 3

Thiago Chagas
Jun 25, 2019 · 5 min read

E aí pessoal, tudo bem com vocês?

Chegamos a terceira parte da série SOLID, “O Shazam da Orientação a objeto”, para que tenhamos boas práticas de programação na construção dos nossos códigos. Caso tenha perdido as duas primeiras partes, elas estarão nestes links:Parte um, Parte dois.

Hoje aprenderemos sobre o Princípio da Substituição de Liskov ou LSP (Liskov Substitution Principle). Mas o que podemos aprender com este princípio??

Para entendermos melhor o LSP vamos voltar ao nosso artigo anterior que se refere ao Princípio Aberto/Fechado .Nele vimos que os mecanismos envolvidos são: Abstração e Polimorfismo. Entretanto, sabemos que nas linguagens tipadas como o C#, quem faz o uso de desses mecanismos é a Herança e ao usarmos a herança, criamos classes derivadas que implementam os métodos abstratos das classes base.

Mas existem regras específicas para o uso da herança? Existem definições melhores para as hierarquias? E o que nos faz criar hierarquias que não obedecem ao princípio do Aberto/Fechado? Para responder a todas estas perguntas é aí que o Princípio da Substiuição de Liskov definido por Barbara Liskov no ano de 1988 nos explica que:

Se para cada objeto o1 do tipo S existe um objeto o2 do tipo T,tal que, para todos os programas P definidos em termos de T,o comportamento de P fica inalterado quando o1 é substituído por o2, então S é um subtipo de T.

E aí, entendeu alguma coisa??

Pode parecer um pouco complicado de se entender, mas com a ajuda do nosso querido Uncle Bob as coisas ficaram mais claras e práticas:

Os subtipos devem ser substituíveis pelos seus tipos de base

Resumindo…

Uma classe base deve poder ser substituída pela sua classe derivada.

A importância do princípio se torna mais clara quando passamos a considerar as consequências da violação.

Entendendo a violação

Se nada como um pato, voa como um pato, mas precisa de bateria, existe um problema de violação”.

Imaginem que temos duas classes: a classe Pato que é a classe base e a classe PatinhoDeBorrachaEletronico que é derivada da classe Pato. Se tivermos a necessidade de que o Pato faça barulho em algum momento e usamos a classe PatinhoDeBorrachaEletronico, já ferimos o princípio pois o PatinhoDeBorrachaEletronico precisa de bateria para fazer o barulho já o Pato não. Com isso temos um problema pois não podemos substituir o PatinhoDeBorrachaEletronico pelo Pato.

Entendendo na Prática

O exemplo clássico do Quadrado e Retângulo.

Sabemos que o Quadrado é um tipo especial de Retângulo e ambos são Paralelogramos(Polígonos de 4 lados) .O quadrado tem uma particularidade que é referente aos lados, todos são iguais.

Nas imagens acima temos as classe Retangulo e Quadrado. A classe Retangulo , por ser a classe base tem as propriedades declaradas como virtual e contém uma propriedade chamada “Area” que faz o cálculo da área do Retângulo.

A classe Quadrado tem como classe base Retangulo,e efetua um “override” das propriedades por causa da particularidade já mencionada.

Na última imagem temos o método VerificarAreaDeRetangulo que apenas mostra os valor das propriedades Altura e Comprimento e efetua o cálculo da área da figura.Já que o quadrado “É UMRetangulo, podemos criar um objeto do tipo Quadrado e passar para o método. Então não teremos mais problemas, OK?Errado!!.A coerência não é exatamente para todos.

Vamos efetuar uma alteração no método VerificarAreaDeRetangulo.

Este método funciona muito bem para um Tipo Retangulo mas quando passamos um Quadrado como parâmetro gera uma exceção.

O verdadeiro problema é que neste método fizemos a suposição de que a alteração do comprimento de um objeto Retangulo deixa a altura inalterada.
É bem razoável supor que mudando o comprimento do Retangulo não afetaria a sua altura.Mas nem todos os objetos que são passados como um Tipo Retangulo pode satisfazer a suposição.Passamos uma instância do objeto Quadrado e não funcionou.Como o Quadrado não pode substituir o Retangulo, o relacionamento entre ambos viola o princípio de Liskov.

Em relação ao antigo método, o Quadrado poderia ser um Retangulo mas em relação ao novo método,o Quadrado não é Retangulo. O comportamento do Quadrado não tem compatibilidade com o que o método espera de um objeto Retangulo. O sofware está relacionado ao comportamento.O princípio de Liskov deixa claro que na orientação à objetos, o relacionamento “É UM” pertence ao comportamento e que pode ser suposto pelo clientes que consomem(novo método);

Este exemplo nos mostra não apenas a violação do princípio da Substituição de Liskov mas também que a orientação a objetos não é apenas para mapeamento de itens da vida real em objetos.Os objetos deve ser abstrações de um conceito.

Uma forma de forçar o LSP e tornar as suposições explícitas seria o Design by Contract. Basicamente o autor de uma classe declara o contrato dessa classe de modo explícito. O contrato é especificado pela declaração de pré-condições e pós-condições para cada método.As pré-condições devem ser verdadeiras para a execução dos métodos. Ao ser concluído, o método garante que as pós-condições são verdadeiras.

Chegamos ao final de mais uma fase da nossa jornada, no próximo artigo falaremos do Princípio da Segregação por Interfaces.

Até lá.

May the force be with you!

Thiago Chagas

Written by

Microsoft Technology Associate (MTA), .Net Developer at Radix

More From Medium

Also tagged Aspnet Mvc

Top on Medium

Top on Medium

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade