Diga que tenho:
interface Thing
{
GetThing();
}
class FastThing : Thing
{
public int GetThing()
{
return 1;
}
}
class SlowThing : Thing
{
public int GetThing()
{
return GetThingFromDatabase();
}
}
Isso é uma violação do princípio da substituição de Liskov?
performance
liskov-substitution
ConditionRacer
fonte
fonte
GetThingFromDatabase()
não é lento o suficiente para tornar isso controverso.Factor4096BitPublicKey();return 1;
tornaria as coisas um pouco mais interessantes.FastThing
porSlowThing
, o LSP não se aplicará. Se você adicionar um comentário aoThing::GetThing
qual diz "É muito rápido", a questão poderá ser discutida.Respostas:
Isso realmente depende. Algumas interfaces têm, por exemplo, restrições de complexidade (elas obviamente não podem ser aplicadas programaticamente). O caso mais básico é "GetThing () fornece um
int
- ou seja, ele pára"; nesse caso, a resposta seria "Não" - ambas as versões do GetThing () param e retornam um int.Mas muitas interfaces têm garantias de desempenho implícitas ou expressamente declaradas, seja em complexidade ou em tempo fixo. Por exemplo, no padrão C ++, é ilegal implementar a biblioteca com uma chamada de bloqueio, exceto onde o padrão o permitir expressamente.
fonte
TL; DR: Não
De acordo com a "Subtipagem Comportamental Usando Invariantes e Restrições" (a formalização do princípio), ela se preocupa principalmente com as propriedades de "segurança" de um tipo de objeto. Propriedades que governam a substituibilidade apenas dentro do contexto das informações de tipo. Um tipo de objeto é ortogonal ao seu desempenho. Portanto, uma diferença de desempenho não é uma violação do Princípio de Substituição de Liskov.
fonte
Que garantias a interface oferece? Como
GetThing
não dá garantias, os subtipos não precisam respeitá-lo.Se a interface era algo como
GetThingInLinearTime
ou se o tipo base é virtual e a implementação padrão é uma complexidade, em seguida, fazendo que a complexidade algorítmica pior seria violar LSP.fonte
O desempenho do software não tem nada a ver com o Princípio de Substituição de Liskov.
O princípio tem a ver com a substituição de subtipos e o impacto comportamental de substituir esse objeto apenas em termos de POO.
A entrada e a saída de
getThing()
permanecem as mesmas nos dois casos e, lenta e rapidamente, provavelmente colocam os objetos no mesmo estado.fonte
Importa o que o próprio Princípio de Substituição de Liskov diz especificamente? Se um subtipo viola as expectativas do consumidor do supertipo, isso parece uma coisa ruim, independentemente de o LSP ser mais restritivo.
Portanto, na minha opinião, se todas as expectativas razoáveis do consumidor de uma abstração são cumpridas pelo subtipo parece ser uma boa generalização do LSP.
No entanto, no exemplo que você postou e com interfaces Java em geral, não está claro que o consumidor da
Thing
interface tenha qualquer expectativa razoável de que deve ser rápida ou lenta. Se os javadocs da interface incluírem linguagem sobre quais operações prometem ser rápidas, pode haver um argumento para um problema com base no desempenho. Mas a convenção Java é certamente que várias implementações têm características de desempenho diferentes.fonte
O tio Bob respondeu a uma pergunta muito semelhante em que afirma que uma violação do LSP exige três partes:
Atrevo-me a supor que essa pergunta tenha uma estrutura semelhante à que ele respondeu, na medida em que não menciona o P que está usando o T e que comportamento o P espera.
Você pode encontrar a resposta dele aqui . (Você precisará rolar para baixo alguns e procurar a resposta do usuário chamado Robert Martin)
fonte