Como posso usar contratos de pré-condição de forma significativa em interfaces D?

StackOverflow https://stackoverflow.com//questions/11682991

  •  12-12-2019
  •  | 
  •  

Pergunta

Quando substituo funções em D por contratos "in", os contratos "in" herdados são verificados.Se falharem, os contratos "in" substituídos serão verificados.Se eu não especificar nenhum contrato, será interpretado como se houvesse um contrato "in" vazio.Portanto, o código a seguir é compilado e executado com êxito.

module main;
import std.stdio;

interface I
{
    void write( int i )
    in
    {
        assert( i > 0 );
    }
}

class C : I
{
    void write( int i )
    {
        writeln( i );
    }
}

int main()
{
    I i = new C;

    i.write( -5 );
    getchar();

    return 0;
}

Eu só quero a pré-condição de I.write() para ser verificado quando eu ligar i.write() já que isso é o que é estaticamente conhecido como suficiente para I.write() para ser executado corretamente pelo compilador.Verificando todas as pré-condições depois o despacho dinâmico me parece estranho do ponto de vista OO, já que o encapsulamento é perdido.

Eu poderia repetir a pré-condição ou escrever in { assert( false ); } em todas as classes que implementam a interface, mas isso é um problema.Isso é um erro de design na linguagem D?Ou existe alguma maneira escalonável adequada de fazer isso?

Foi útil?

Solução

http://dlang.org/dbc.html

Se uma função em uma classe derivada substituir uma função em sua superclasse, então apenas um dos contratos in da função e de suas funções base deverá ser satisfeito.A substituição de funções torna-se então um processo de flexibilização dos contratos.

Uma função sem contrato significa que quaisquer valores dos parâmetros da função são permitidos.Isto implica que se qualquer função em uma hierarquia de herança não tiver contrato, então nos contratos sobre funções que a substituem não terá efeito útil.

Por outro lado, todos os contratos externos precisam ser satisfeitos, de modo que a substituição de funções torna-se um processo de estreitamento dos contratos externos.

Na verdade, é um quebra-cabeça de design difícil quando o comportamento polimórfico é questionado.Veja, por exemplo, este relatório de bug com uma longa discussão relacionada: http://d.puremagic.com/issues/show_bug.cgi?id=6857

Com relação à questão de como obter o comportamento desejado - o mixin sempre funciona quando copiar e colar precisa ser evitado, mas não tenho certeza se é correto fazê-lo do ponto de vista do paradigma Design By Contract.Infelizmente, preciso de alguém mais competente teoricamente neste assunto.

Outras dicas

Uma pré-condição em D é um requisito para que a função seja executada corretamente.Se você sobrecarregar a função, escrever um novo código para ela, a pré-condição antiga - que é um requisito para o código antigo - não é necessariamente um requisito para o novo código.

Portanto, esta questão, embora não seja discutida diretamente sobre interfaces, é http://d.puremagic.com/issues/show_bug.cgi?id=6856

Isso pode ser difícil de entrar, porém, Walter é fã de não fazer mudanças significativas.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top