As mudanças na performance violam o Princípio da Substituição de Liskov?

14

Digamos que eu tenha:

interface Thing
{
    GetThing();
}

class FastThing : Thing 
{
    public int GetThing()
    {
        return 1;
    }
}

class SlowThing : Thing
{
    public int GetThing()
    {
        return GetThingFromDatabase();
    }
}

Isto é uma violação do Princípio de Substituição de Liskov?

    
por ConditionRacer 10.02.2013 / 00:36
fonte

6 respostas

14

Isso realmente depende. Algumas interfaces têm, por exemplo, restrições de complexidade (obviamente, elas não podem ser aplicadas de forma programática). O caso mais básico é "GetThing () dá um int - ou seja, ele pára", nesse caso, a resposta seria "Não" - ambas as versões de GetThing () interrompem e retornam um int.

Mas muitas interfaces têm implícito ou expressamente afirmado garantias de desempenho, seja em complexidade ou em tempo fixo. Por exemplo, no Padrão C ++, é ilegal implementar a biblioteca com uma chamada de bloqueio, exceto quando o Padrão permitir expressamente.

    
por 10.02.2013 / 00:42
fonte
8

TL; DR: Não

De acordo com o "Subtipagem comportamental usando invariantes e restrições" (a formalização do princípio) diz respeito principalmente às propriedades de "segurança" de um tipo de objeto. Propriedades que governam a substituibilidade somente dentro do contexto de informações de tipo. Um tipo de objeto é ortogonal ao seu desempenho. Portanto, uma diferença no desempenho não é uma violação do Princípio de Substituição de Liskov.

    
por 10.02.2013 / 01:00
fonte
6

Quais garantias a interface faz? Como GetThing não oferece garantias, os subtipos não precisam respeitá-lo.

Se a interface fosse algo como GetThingInLinearTime ou se o tipo base fosse virtual e a implementação padrão fosse uma complexidade, então piorar a complexidade algorítmica iria violar o LSP.

    
por 10.02.2013 / 03:20
fonte
4

O desempenho do software não tem nada a ver com o Princípio de Substituição Liskov.

O princípio tem a ver com a substituição de subtipos e o impacto comportamental da substituição desse objeto apenas em termos OOP.

A entrada e a saída de getThing() permanecem as mesmas para ambos os casos, e tanto lenta quanto rápida provavelmente colocam os objetos no mesmo estado.

    
por 10.02.2013 / 01:04
fonte
1

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 ser 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 atendidas pelo subtipo parece ser uma boa generalização do LSP.

No entanto, no exemplo que você publicou e com interfaces Java em geral, não está claro se o consumidor da interface Thing tem uma expectativa razoável de que seja rápido ou lento. Se os javadocs da interface incluíssem a linguagem sobre quais operações seriam prometidas rápidas, então poderia haver um argumento para um problema por motivos de desempenho. Mas a convenção Java certamente tem várias implementações para ter características de desempenho diferentes.

    
por 10.02.2013 / 03:32
fonte
-1

O tio Bob respondeu a uma pergunta muito semelhante, na qual ele afirma que uma violação do LSP requer três partes:

The Type T, the Subtype S, and the program P that uses T but is given an instance of S.

Eu arriscaria adivinhar que essa pergunta tem uma estrutura semelhante à que ele respondeu, pois não menciona o P que está usando o T e qual comportamento o P espera.

Você pode encontrar a resposta aqui . (Você precisará rolar para baixo e procurar respostas do usuário chamado Robert Martin)

    
por 06.09.2013 / 08:21
fonte