Estoy leyendo el libro "Learning TypeScript" de Remo Jansen. En una sección, el autor describe cómo crear un marco MVC de prueba de concepto muy simple que incluye cómo crear la Model
clase y dice lo siguiente:
Se debe proporcionar un modelo con la URL del servicio web que consume. Vamos a utilizar un decorador de clase llamado ModelSettings para establecer la URL del servicio que se consumirá. Podríamos inyectar la URL del servicio a través de su constructor, pero se considera una mala práctica inyectar datos (a diferencia de un comportamiento) a través de un constructor de clase .
No entiendo esa última oración. En particular, no entiendo lo que significa "inyectar datos". Me parece que en casi todas las introducciones a las clases de JavaScript que usan ejemplos demasiado simplificados, los datos se introducen (¿"inyectados"?) En el constructor a través de sus parámetros. Por ejemplo:
class Person {
constructor(name) {
this.name = name;
}
}
Ciertamente pienso name
en los datos, no como el comportamiento, y se incluye universalmente en este tipo de ejemplo como un parámetro constructor, y nunca se menciona que esta sea una mala práctica. Por lo tanto, supongo que estoy malentendiendo algo en la cita anterior, ya sea lo que se entiende por "datos" o por "inyectar" u otra cosa.
Sus respuestas podrían incluir explicaciones de cuándo, dónde, cómo y por qué usar decoradores en JavaScript / TypeScript, ya que sospecho que ese concepto está íntimamente relacionado con la comprensión que busco. Sin embargo, lo que es más importante, quiero comprender de manera más general qué se entiende por inyectar datos a través de un constructor de clases y por qué eso es malo.
Para dar más contexto a la cita anterior, esta es la situación: Model
se crea una clase que, en este ejemplo, se utilizará para crear modelos de bolsa, uno para NASDAQ y otro para NYSE. Cada modelo requiere la ruta del servicio web o el archivo de datos estáticos que proporcionará los datos sin procesar. El libro establece que se debe usar un decorador para esta información, en lugar de un parámetro constructor, lo que lleva a lo siguiente:
@ModelSettings("./data/nasdaq.json")
class NasdaqModel extends Model implements IModel {
constructor(metiator : IMediator) {
super(metiator);
}
...
}
Simplemente no he entendido por qué debería agregar la URL del servicio a través del decorador en lugar de simplemente como un parámetro para el constructor, por ejemplo
constructor(metiator : IMediator, serviceUrl : string) {...
fuente
Respuestas:
Le daré al autor el beneficio de la duda y tal vez las cosas sean así para Typecript, pero de lo contrario, en otros entornos, esa es una afirmación totalmente infundada que no debe tomarse en serio.
Fuera de mi cabeza, puedo pensar en una variedad de situaciones donde pasar datos a través del constructor es bueno, algunos son neutrales, pero ninguno es malo.
Si una clase particular depende de un dato particular para estar en un estado válido y ejecutarse correctamente, tiene mucho sentido exigir esos datos en el constructor. Una clase que representa un puerto serie podría tomar el nombre del puerto, un objeto de archivo podría requerir el nombre del archivo, un lienzo de dibujo que requiera su resolución, etc. A menos que pase los datos en el constructor, es posible que pueda tener el objeto en un estado no válido que tiene que ser observado y verificado. De lo contrario, puede verificar solo en la instanciación de objetos y luego asumir que funciona en su mayor parte. Los autores afirman que esa situación beneficiosa es imposible.
Además, la decisión de prohibir el paso de datos en un constructor también hace que prácticamente todos los objetos inmutables sean imposibles. Los objetos inmutables tienen una variedad de beneficios en muchas situaciones, y todos estos se eliminarían con la política del autor.
Incluso si los objetos mutables son lo que quieres, ¿cómo es esta mala práctica?
a favor de:
¿El autor realmente piensa que lo primero es una mala práctica y que siempre debería ir con la opción 2? Creo que es una locura hablar.
Entonces, como no tengo el libro, y no lo leería de todos modos, incluso si lo tuviera, vería esa declaración y casi cualquier declaración general en este momento con una gran cantidad de sospecha.
fuente
Creo que depende del contexto qué tipo de modelo se está discutiendo aquí. No tengo el libro de Remo, pero supongo que el modelo es un tipo de modelo de servicio, que necesita recuperar los datos de un servicio web remoto. Si ese es el caso, al ser un modelo de servicio web, es mejor pasar todos los datos necesarios como argumentos en los métodos del servicio web, haciendo que el servicio sea apátrida.
El servicio sin estado tiene varias ventajas, por ejemplo, cualquiera que lea una llamada al método de servicio no necesita buscar cuando el servicio se construye para conocer los detalles del servicio llamado. Todos los detalles se muestran en los argumentos que se utilizan en la llamada al método (excepto la url remota).
fuente
Solo adivinando.
Si escucho 'inyectar comportamiento, no datos', pensaría en, en lugar de hacer esto:
(Perdón por el ejemplo en pseudocódigo):
Para hacer esto:
De esta manera puede cambiar el comportamiento del ruido siempre, hacerlo aleatorio, dependiente de una variable interna ...
Creo que se trata de la regla 'favor compuesto sobre heredar'. Lo cual es una gran regla, debo decir.
Esto NO SIGNIFICA que no puede 'inyectar' el nombre al Objeto 'Persona', obviamente, porque ese nombre es puramente información comercial. Sin embargo, en el ejemplo que se da, el servicio web, la URL es algo que necesita para generar algo de alguna manera que se conecta un servicio. Eso de alguna manera es un comportamiento: si inyecta la URL, inyecta los 'datos' necesarios para construir un 'comportamiento', por lo que en ese caso es mejor hacer que el comportamiento esté fuera e inyectarlo listo para usar: en su lugar, inyecte una inyección de URL una conexión utilizable o un generador de conexiones utilizable.
fuente