2012-07-27 14 views
5

Cuando anulo las funciones en D con contratos "en", se verifican los contratos heredados "en". Si fallan, se verifican los contratos "en" anulados. Si no especifico ninguno en el contrato, se interpreta como si hubiera un contrato "in" vacío. Entonces el siguiente código se compila y se ejecuta con éxito.¿Cómo puedo usar de manera significativa los contratos de precondición en las interfaces D?

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; 
} 

que sólo quieren la condición previa de I.write() comprobación cuando llamo i.write() ya que eso es lo que se conoce de forma estática a ser suficiente para I.write() para funcionar correctamente por el compilador. Comprobando todas las condiciones previas después de el envío dinámico me parece extraño desde una perspectiva OO ya que se pierde la encapsulación.

Podría repetir la precondición o escribir in { assert(false); } en todas las clases implementando la interfaz, pero eso es un problema. ¿Es eso un error de diseño en el lenguaje D? ¿O hay alguna forma adecuada y escalable de hacerlo?

Respuesta

3

http://dlang.org/dbc.html

Si una función en una clase derivada anula una función de su clase súper, entonces sólo uno de los en los contratos de la función y sus funciones base debe ser satisfecho. Las funciones prioritarias se convierten en un proceso de aflojamiento de los contratos.

Una función sin contrato implica que se permiten los valores de los parámetros de la función. Esto implica que si alguna función en una jerarquía de herencia no tiene un contrato, entonces en los contratos sobre funciones que anulan no tiene ningún efecto útil.

Por el contrario, todos los contratos de salida deben ser satisfechos, por lo que las funciones superiores se convierte en un proceso de ajuste de los contratos de salida.

En realidad, es un rompecabezas de diseño difícil cuando se cuestiona el comportamiento polimórfico. Mire, por ejemplo, en este informe de error con una discusión larga relacionada: http://d.puremagic.com/issues/show_bug.cgi?id=6857

En cuanto a la pregunta de cómo lograr un comportamiento deseado, Mixin siempre funciona cuando se debe evitar copiar y pegar, pero no estoy seguro de que esté bien hacerlo desde el paradigma del diseño por contrato. Lamentablemente, necesitamos alguien más teóricamente competente en este consejo de preguntas.

+0

No estoy seguro de si la página de documentación no está desactualizada. Tendría que mirar TDPL para estar seguro, pero hay un error similar al problema del OP: http://d.puremagic.com/issues/show_bug.cgi?id=6549 – jpf

+0

@jpf Esa es una solicitud de mejora. Algunas personas quieren que se modifique el idioma con respecto a este tema. La documentación es correcta con respecto al comportamiento actual. –

+0

Oh cierto, no me di cuenta de eso. – jpf

0

Una condición previa en D es un requisito para que la función se ejecute correctamente. Si sobrecarga la función, escribe un código nuevo para ella, la precondición anterior, que es un requisito para el código anterior, no es necesariamente un requisito para el nuevo código.

Cuestiones relacionadas