Prácticas para modelos de dominio en Javascript (con frameworks)

8

Esta es una pregunta con la que he estado yendo y viniendo por un tiempo, y busqué y no encontré nada: ¿cuáles son las prácticas aceptadas que rodean la duplicación de modelos de dominio en Javascript para una aplicación web, cuando uso un marco como Backbone? o Knockout?

Dada una aplicación web de un tamaño no trivial con un conjunto de modelos de dominio en el lado del servidor, ¿deberíamos duplicar estos modelos en la aplicación web (ver el ejemplo al final)? ¿O deberíamos usar la naturaleza dinámica para cargar estos modelos desde el servidor?

En mi opinión, los argumentos para duplicar los modelos están en facilitar la validación de los campos, asegurando que los campos que se esperaban que estén presentes, de hecho, etc. Mi enfoque es tratar el código del lado del cliente como una aplicación casi separada, haciendo cosas triviales. solo y depender del servidor para datos y operaciones complejas (que requieren datos que el lado del cliente no tiene). Creo que tratar el código del lado del cliente de esta manera es similar a la separación entre entidades de un ORM y los modelos utilizados con la vista en la capa de IU: pueden tener los mismos campos y estar relacionados con el mismo concepto de dominio, pero son distintos cosas.

Por otro lado, me parece que duplicar estos modelos en el lado del servidor es una clara violación de DRY y es probable que conduzca a resultados diferentes en el lado del cliente y del servidor (donde una parte se actualiza pero la otra no) ) Para evitar esta violación de DRY, simplemente podemos usar el dinamismo de Javascripts para obtener los nombres de campo y los datos del servidor cuando sea necesario.

Entonces: ¿existen pautas aceptadas sobre cuándo (y cuándo no) repetirse en estas situaciones? ¿O esto es algo puramente subjetivo, basado en el proyecto y los desarrolladores?

Ejemplo

Modelo del lado del servidor

class M 
{
    int A
    DateTime B
    int C
    int D = (A*C)
    double SomeComplexCalculation = ServiceLayer.Call();
}

Modelo del lado del cliente

function M(){
    this.A = ko.observable();
    this.B = ko.observable();
    this.C = ko.observable();
    this.D = function() { return A() * C(); }
    this.SomeComplexCalculation = ko.observalbe();
    return this;
}l
M.GetComplexValue = function(){
    this.SomeComplexCalculation(Ajax.CallBackToServer());
};

Me doy cuenta de que esta pregunta es bastante similar a esta , pero creo que se trata más de desvincular casi por completo la aplicación web del servidor, donde esa pregunta se trata de hacer esto solo en el caso de cálculos complejos.

Andy Hunt
fuente
¿Su pregunta es más sobre cómo gestiona las instancias de objetos en el lado JS para componentes desacoplados, o más sobre la comunicación entre el cliente y el servidor? Además, con respecto a esto M.getComplexValue(), es posible que desee analizar el patrón "Promesa" como una forma de minimizar el infierno de devolución de llamadas mientras permite que todas las operaciones sean (potencialmente) asíncronas.
Darien
Se trata más de si usar objetos definidos en JS (como en el ejemplo) o un objeto anónimo con campos dinámicamente poblados
Andy Hunt

Respuestas:

0

Creo que los buenos patrones de diseño y un marco como Breeze pueden ayudarte. No repita el modelo de dominio en el cliente nuevamente, déjelo en el servidor pero use Breeze para llevar el modelo al cliente.

Aquí hay un gran ejemplo del uso de breezejs con los patrones de repositorio y unidad de trabajo.

https://github.com/yagopv/DurandalAuth

El modelo de dominio se mantiene en el servidor y brisa lee los metadatos y crea las entidades localmente desde el servidor. Creo que esta es una gran solución a su problema. Obtiene acceso de tipo de marco de entidad local localmente a través de JS y puede mantener su modelo en el servidor. Creo que logra un buen equilibrio de los problemas que mencionó en su pregunta.

Roger Brogan
fuente
2
¿Cómo responde esto a la pregunta que se hace? Tal como está, esto se lee más como un aviso de spam.
mosquito
1
Es una respuesta bastante directa. La pregunta es repetir el modelo de dominio en el cliente nuevamente. Mi respuesta es no dejarlo en el servidor, sino la brisa del usuario para llevar el modelo al cliente. No estoy afiliado con brisa o durandal. Acabo de encontrar los marcos útiles.
Roger Brogan
3

Su pregunta real es un poco más general, por lo que es difícil de responder, pero su ejemplo de validación de formulario es un poco más específico, por lo que intentaré seguir con esa.

Como dijiste, siempre debes estar SECO, tanto como sea posible. Eso es algo bueno a tener en cuenta como desarrollador. Sin embargo, debe distinguir entre las cosas que son similares y debe evitar repetirlas con las cosas que hacen cosas similares, pero tienen propósitos diferentes .

Vayamos a su ejemplo de validación de formulario. El propósito de su código de validación en el servidor es asegurarse de que tiene la dirección de correo electrónico del usuario, por ejemplo, para ponerla en la base de datos. Entonces, como es imprescindible que su proceso de registro tenga la dirección de correo electrónico del usuario, lo está verificando durante el proceso de registro.

¿Pero cuál es el propósito de su código JavaScript del lado del cliente? Sí, realiza la validación en el campo de entrada de correo electrónico, pero la idea es: ¡Verificar si el usuario ya ingresó su dirección de correo electrónico, si no, mostrarle una alerta ANTES de enviarla al servidor! Por lo tanto, el propósito de la validación del formulario del lado del cliente es dejar de enviar datos inútiles al servidor y mostrar un mensaje de error después de unos segundos para volver a enviar el formulario de solicitud. ¿Por qué? porque es molesto para los usuarios. ¿Ahora cree que debería mantener su función de validación de formularios solo en el servidor? No, porque tienen diferentes propósitos.

El propósito de la validación del formulario en el lado del cliente no es que no pueda confiar en los usuarios, vamos a verlo , pero es más una cuestión de UX donde estás tratando de evitar comunicarte con el servidor solo para obtener el mensaje de error de validación; Sin embargo, el propósito de la validación del formulario en el lado del servidor es que no puedo confiar en los usuarios, veamos qué me están pidiendo que haga , y un Usuario también puede ser una solicitud de API, sin ningún usuario humano en el lado del cliente.

Si lo miras así, tu ejemplo de validación de formulario estaría totalmente bien, sin hacerte sentir MOJADO.

Con respecto a su pregunta real, no intente mantener todo en el servidor o todo en el cliente; Realmente depende de la tarea. Digamos que si necesito analizar un archivo CSV grande-grande para el usuario y solo tengo un centenar de usuarios en el sitio web y sé que tengo usuarios móviles, entonces puedo analizar ese archivo en el servidor y luego generar un archivo marcado para digerir al cliente. Sin embargo, si tengo millones de usuarios, entonces trataría de analizar el archivo en sus máquinas, utilizando sus navegadores web para usar su poder de procesamiento para evitar quemar nuestro servidor. Por lo tanto, la funcionalidad de análisis podría estar en el servidor o en el cliente, lo que tenga más sentido.

Sin embargo, si no está seguro de dónde guardar sus cosas, entonces diría que las guarde en el servidor y luego envíe los resultados a los usuarios: evite el código duplicado tanto en el servidor como en el cliente.

Mahdi
fuente
Me encantaría saber por qué la respuesta recibió un voto negativo. Realmente aprecio que también compartas tus pensamientos.
Mahdi