en el ejemplo anterior, comenzamos con una clase, pero queremos agregar la capacidad de ofrecer diferentes tipos de paquetes de automóviles. Para ello, la fábrica utiliza prototipos alternativos para diferentes paquetes de automóviles. He utilizado esta técnica para almacenar varias implementaciones de una interfaz de reproductor multimedia, eligiendo el prototipo correcto basado en el tipo de medio que el reproductor necesitaba controlar.,
instanceof
no hacer la comprobación del tipo de la manera que usted espera similar controles a hacer en el establecimiento inflexible de tipos de idiomas. En su lugar, realiza una comprobación de identidad comparando el objeto
__proto__
con la propiedad
Constructor.prototype
.
no funcionará en diferentes reinos de memoria como iframes, por ejemplo (una fuente común de errores en incrustaciones de JavaScript de terceros). Tampoco funciona si tu Constructor.prototype
es reemplazado.,
también fallará si comienza con una clase o constructor (que devuelve this
, vinculado a Constructor.prototype
), y luego cambia a exportar un objeto arbitrario (no vinculado a Constructor.prototype
), que es lo que sucede cuando cambia de un constructor a un fábrica.
En resumen, instanceof
es otra forma en la que cambiar de un constructor a una fábrica es un cambio radical.
beneficios de usar la clase
- sintaxis conveniente y autónoma.,
- Una única forma canónica de emular clases en JavaScript. Antes de ES6, había varias implementaciones competidoras en bibliotecas populares.
- más familiar para las personas con antecedentes lingüísticos basados en clases.
inconvenientes de usar class
todos los inconvenientes del constructor, además:
- tentación para los usuarios de crear jerarquías de clase problemáticas usando la palabra clave
extends
.,
las jerarquías de clase conducen a un montón de problemas bien conocidos en el diseño orientado a objetos, incluyendo el problema de la clase base frágil, el problema del gorila banana, el problema de duplicación por necesidad, y así sucesivamente. Desafortunadamente, la clase se extiende como las bolas permiten lanzar y las sillas permiten sentarse. Para obtener más información, lea «los dos pilares de JavaScript: Prototypal OO» y «dentro de la espiral de muerte del equipo de desarrollo».,
vale la pena señalar que tanto los constructores como las fábricas también se pueden usar para crear jerarquías de herencia problemáticas, pero con la palabra clave `extends`, class crea una asequibilidad que lo lleva por el camino equivocado. En otras palabras, lo alienta a pensar en términos de relaciones inflexibles (y a menudo incorrectas), En lugar de las relaciones compositivas más flexibles que tienen o pueden hacer.
en Una posibilidad es una característica que ofrece la oportunidad de realizar una determinada acción., Por ejemplo, una perilla permite girar, una palanca permite tirar, un botón permite presionar, etc<
los beneficios de usar fábricas
Las fábricas son mucho más flexibles que las funciones de constructor o las clases, y no conducen a las personas por el camino equivocado tentándolas con la palabra clave `extends` y jerarquías de herencia profundas. Hay muchos mecanismos de reutilización de código más seguros que debe favorecer sobre la herencia de clases, incluyendo funciones y módulos.,
devuelve cualquier objeto arbitrario y usa cualquier prototipo arbitrario
por ejemplo, puede crear fácilmente varios tipos de objetos que implementan la misma API, por ejemplo, un reproductor multimedia que puede crear instancias de reproductores para varios tipos de contenido de vídeo que utilizan diferentes API bajo el capó, o una biblioteca de eventos que puede emitir eventos DOM o eventos de socket web.
Las fábricas también pueden crear instancias de objetos en contextos de ejecución, aprovechar los grupos de objetos y permitir modelos de herencia de prototipos más flexibles.,
sin preocupaciones de refactorización
nunca tendría la necesidad de convertir de una fábrica a un constructor, por lo que la refactorización nunca será un problema.
No ‘ new ‘
No hay ambigüedad sobre el uso de new
. No. (hará que this
se comporte mal, vea el siguiente punto).
el comportamiento estándar `this`
this
se comporta como lo haría normalmente, por lo que puede usarlo para acceder al objeto padre. Por ejemplo, dentro de player.create()
, this
se refiere al jugador, al igual que cualquier otro método de invocación., call()
y apply()
reasignar this
como se esperaba.
a algunas personas les gusta la forma en que `myFoo = createFoo()` lee
- no crea un enlace desde la instancia a
Factory.prototype
— pero esto es realmente bueno porque no obtendrá uninstanceof
engañoso. En su lugar, instanceof
siempre fallará. Ver beneficios.
-
this
no se refiere al nuevo objeto dentro de la fábrica. Ver beneficios.,
- Puede funcionar más lento que una función de constructor en benchmarks de microoptimización. El camino lento sigue siendo muy rápido — millones de ops / seg en un ordenador antiguo. Es más probable que esto sea una preocupación en el código de la biblioteca o del marco que en el código de la aplicación. Siempre benchmark desde la perspectiva del Usuario antes de usar micro-optimizaciones.
conclusión
en mi opinión, class
puede tener una sintaxis conveniente, pero eso no puede compensar el hecho de que atrae a los usuarios incautos a estrellarse en las rocas de la herencia de clase., También es arriesgado porque en el futuro, es posible que desee actualizar a una fábrica, pero todas sus llamadas estarán estrechamente acopladas a la función constructor debido a la palabra clave new
y el hecho de que pasar de clases a fábricas es un cambio radical.
Puede estar pensando que solo puede refactorizar los sitios de llamadas, pero en equipos grandes, o si la clase con la que está trabajando es parte de una API pública, podría romper el código que no está bajo su control. En otras palabras, no siempre puedes asumir que refactorizar a las personas que llaman es una opción.,
lo bueno de las fábricas es que no solo son más potentes y flexibles, sino que también son la forma más fácil de alentar a equipos enteros y bases de usuarios de API completas a usar patrones que sean simples, flexibles y seguros.