Se você acha que, porque todo quadrado é um retângulo na geometria, também deve ser em um sistema, está na hora de rever seus conceitos. Ou você ainda é do tempo que herança se define como "é um". Um quadrado "é um" retângulo.
Imagine o retângulo:
public class Retangulo
{
public int Altura {get; set;}
public int Largura {get; set;}
public int Area {get; set;}
}
E um quadrado:
public class Quadrado : Retangulo
{
private int _lado;
public int Altura
{
get
{ return _lado; }
set
{
this._lado = value;
}
}
//mesma coisa para largura
//usando a variável _lado
}
Neste caso, um quadrado herda de um retângulo. Só que, em um retângulo, os lados variam independentemente. O que acontece com este teste unitário se ele receber um quadrado?
public void Area_eh_igual_altura_vezes_largura()
{
Retangulo r = ObterRetangulo();
r.Altura = 10;
r.Largura = 5;
Assert.AreEqual(50, r.Area);
}
Ele falha! Ao setar a largura para 5, acabei setando também a altura, deixando a área com 25, e não 50. Oras, mas um retângulo não é um quadrado?
A questão é que, neste caso, não é. Ele é conceitualmente, mas não no caso de reaproveitamento de código hierarquicamente, que é o que herança faz. Herança não tem nada a ver com "é um". Esse conceito até ajuda, mas não é sempre verdadeiro, como acabo de mostrar.
O quadrado quebra o Princípio de substituição de Liskov, onde uma classe filha deve substituir plenamente uma classe base. Se um conceito era válido na base, deve ser válido na filha. Nesse caso, o conceito é que os lados variam independentemente, o que não foi respeitado pelo quadrado. Em sistemas, se você não respeita o princípio, a aplicação de polimorfismo pode acabar introduzindo bugs horrorosos, como foi exatamente o caso com o teste.
Postado na(s) categoria(s)
Arquitetura
pelo
giovanni bassi em 26 de fevereiro de 2009 às 12:41
| Tags:
arquitetura,
oo
06fa69d7-2e42-416c-a667-aec63b3f88b5|2|5.0