2009-02-18 9 views
5

De alguna manera debo haber pasado por alto el principio de OOP de "dígame, no pregunte" todos estos años porque me acabo de enterar hace un par de días por primera vez.¿Se aplica "indicar, no preguntar" a la validación de entrada del usuario?

Pero el contexto era una discusión sobre el código de validación que se había movido de una página de formulario web ASP.NET a un objeto de datos/negocio, y no había un método "Validate()", solo un método de guardado sí mismo hizo la validación y (supuestamente) planteó una excepción. Le pregunté por qué esto fue diseñado de esta manera y me dirigieron al principio de "decir, no preguntar" de OOP, del que nunca había oído hablar, entonces miramos juntos en Google y me educaron inmediatamente. ;)

Aún así, algo no huele bien, no se debe restregar los datos antes de que sean transferidos lejos del usuario y hacia la capa de negocios donde se procesa y/o recoge, en lugar de al revés ? Estoy confundido sobre cómo esto contribuye a un buen diseño.

Parece que la regla de "decir, no preguntar" se refiere a la idea de que no debe preguntar al objeto de destino sobre el estado del objeto de destino, y que el principio nunca se pensó realmente para aplicar a los datos pasando a el objeto de destino.

Respuesta

2

Estoy de acuerdo con AviewAview, pero woul Sólo d lanzar excepciones si el usuario dice (no si le pide):

public Foo 
{ 
    bool Validate(Baz bar) 
    { 
     if(!is_number(bar)) return false; 
     return true; 
    } 

    AssignBar(Baz bar) 
    { 
     if (!Validate(bar)) throw numberexception(); 
    } 
} 

Tell:

try 
{ 
    foo.AssignBar(bar); 
} 
catch(numberexception e) 
{ 
    alert('Not a number!'); 
} 

Pregunte:

if (foo.Validate(bar) 
{ 
    foo.AssignBar(bar); 
} 
else 
{ 
    alert('Not a number!'); 
} 

Así AssignBar espera una barra válido y se produce una excepción si no es así, pero también proporcionamos un método para Validar que no arroja una excepción.

+3

excepciones están bien para el manejo de casos inesperados (memoria insuficiente/disco está lleno/conexión cerrada/transacción distribuida falló) - la validación de los datos enviados por el usuario no es inesperado. utilice el enfoque "controlador" en su lugar - solo llame a validate_number (invalid_handler_callback) –

3

Pensé que sonaba como un montón de "Mejores prácticas" y "Metodologías de diseño" que salieron mal, pero ahora tiene sentido para mí. Mírelo de esta manera:

Imagine poner validación en el Objeto Comercial, pero el "qué hago si la validación falla" en la capa de presentación. Esto permitiría que múltiples capas de presentación reutilicen la misma lógica de validación, pero manejen errores de forma diferente.

public Foo 
{ 
    Validate(Baz bar) 
    { 
     if(!is_number(bar)) throw numberexception(); 
    } 

    AssignBar(Baz bar) 
    { 
     Validate(bar); 
    } 
} 


//... 

try 
{ 
    foo.AssignBar(bar); 
} 
catch(numberexception e) 
{ 
    alert('Not a number!'); 
} 

nb se puede discutir todo lo que quieran de lanzar excepciones, que se entiende como un ejemplo. Volver estados, Bools, lo que quiera.

0

Me pregunto si esto es más un problema de "separación de preocupaciones" que "no preguntes". ¿De quién es la responsabilidad de validar los datos? Podría decirse que es la cosa responsable de persistir.

Por supuesto, a veces es útil validar los datos en varias capas. Si este es el caso para su aplicación, no tengo ningún problema para exponer la lógica de validación en la capa de "usuario". Pero aún así lo quiero en la capa de negocios.

Cuestiones relacionadas