prototipos prototipo patrones patron ejemplo diseño design-patterns prototype-pattern

design-patterns - patrones - prototipos java



Preguntas sobre el patrón de prototipo (3)

Patrón de prototipo

El prototipo da como resultado un objeto clonado que es diferente del objeto original. El estado del original es el mismo que el del clon, en el momento de la clonación. A partir de entonces, cada objeto puede sufrir un cambio de estado. Puedes pensar en esto como algo similar, fotocopiar el original y luego modificar la fotocopia en algunos lugares.

Ejemplo

  • Duplicación de DVD: Duplicación del DVD maestro para crear varias copias
  • Objeto de informe: considere un objeto de informe que contiene información procesada para pasar a la GUI. El informe original contiene los datos en orden ascendente. Ahora, usando este patrón uno puede crear un informe similar pero con datos ordenados en orden descendente.

Beneficios

  • Rendimiento: la clonación (utilizando MemberwiseClone ) es considerablemente menos costosa que la creación de un nuevo objeto nuevo (con un nuevo operador ). Tenga en cuenta que es necesario anular el MemberwiseClose() para realizar una copia profunda.
  • Los objetos se pueden clonar de forma muy dinámica, sin ninguna insistencia en la instanciación inicial. El primer objeto creado se puede crear en cualquier momento en la ejecución de la aplicación, y la duplicación adicional puede tener lugar en cualquier momento a continuación.

Cuándo usarlo

  • Cuando las clases para crear instancias se especifican en tiempo de ejecución, por ejemplo, mediante carga dinámica.
  • Cuando las instancias de una clase pueden tener una de las pocas combinaciones diferentes de estado. Puede ser más conveniente instalar una cantidad correspondiente de prototipos y clonarlos en lugar de crear una instancia de la clase manualmente, cada vez con el estado apropiado.

Comparación con el patrón de fábrica

El patrón de prototipo permite que un objeto cree objetos personalizados sin conocer su clase ni detalles sobre cómo crearlos. Por lo tanto, es este aspecto que se parece mucho al patrón Método de fábrica. En ambos patrones, el cliente puede crear cualquiera de los objetos de clase derivados sin saber nada sobre su propia estructura.

Pero la diferencia entre los dos patrones es el hecho de que para el Factory Method concentra en crear un objeto de un tipo de objeto no existente como una fresh creation (entendiendo el subtipo exacto de la clase Creador). El patrón Prototype usa la clase en sí, especialmente la clase derivada para self duplication acción de self duplication .


Patrón de método de fábrica

En este patrón, el cliente (o consumidor) le pide al Creador (o fábrica) un tipo específico de objeto de una jerarquía de clases. El método Creador de la clase de fábrica delega la creación del objeto específico a las clases derivadas y devuelve el objeto de la clase del tipo solicitado por el cliente. En esencia, tiene un único punto de contacto para la creación de varios objetos de una jerarquía de clases.

Puede pensar en esto yendo a un contador de boletos de avión (controlador) y pidiendo un boleto dando su preferencia del tipo de boleto (primera clase, ejecutivo o economía). Al usuario no le preocupa cómo se genera el ticket, aunque en una representación de objeto, la primera clase y el ticket económico se derivan de la clase de ticket base.

Cuándo usar

  • La flexibilidad es importante (bajo acoplamiento)
  • Los objetos se pueden extender en subclases
  • Existe una razón específica por la que una subclase se elegiría sobre otra: esta lógica forma parte del Método de Fábrica.
  • Un cliente delega responsabilidades a subclases en jerarquías paralelas.


Patrón abstracto de fábrica

La fábrica abstracta va un paso más arriba (más abstracta) que el patrón de método de fábrica. En este caso, uno puede tener no solo una, sino varias fábricas con ligeras variaciones. Es responsable de crear objetos que pertenecen a familias de jerarquías de clase en lugar de solo una jerarquía de clases única.

Ya existe una clase Factory específica. Pero la fábrica tendrá métodos ligeramente diferentes. Cada método puede producir una instancia. El cliente puede elegir el método apropiado y obtener la instancia.

Si toma el ejemplo de Architectural Design perfecto basado en MVC , el cliente será una clase de controlador de negocios, mientras que Concrete Products serán todas las entidades de negocios. Las fábricas son controladores auxiliares (auxiliares). Trabajan en asociación con una solicitud del Controlador Comercial.

Cuándo usar

  • Se espera que el sistema sea independiente de cómo se crean los productos. Incluso puede esperar independencia sobre cómo se componen y representan los productos. El término producto se aplica al objeto finalmente resultante que un desarrollador del cliente necesitaría utilizar al invocar sus métodos.
  • El sistema que debe ser configurable con una de las múltiples familias de productos. Por lo tanto, la selección real de la familia no será en el momento de la codificación sino en un momento de configuración posterior.
  • La familia de productos está diseñada para funcionar siempre en conjunto.
  • La creación es para una biblioteca de productos. Lo que más se preocupa aquí es la interfaz relevante y no la implementación.

Estoy aprendiendo sobre los diferentes patrones de diseño y tengo la fuerte sensación de que me falta una pieza (o piezas) esencial para comprender este patrón en particular.

En todos los sitios web que he visto y en el libro de GoF, veo el método de clonación. Por lo que entiendo, tenemos algún tipo de objeto que podemos clonar cuando necesitamos versiones diferentes de ese objeto, pero no queremos tener que crear manualmente cada uno usando el comando "nuevo" (como en Java). Esto puede ocultar su implementación concreta. Entonces, cuando hacemos clonaciones, podemos modificar un poco el clon y convertirlo en lo que necesitamos sin tener que saber cómo crear originalmente ese objeto de la manera difícil. ¿Es esto mi pensamiento correcto?

También me dijeron que esto puede reducir la creación de subclases y, a continuación, reducir la cantidad de clases que debe realizar. No entiendo muy bien esta parte. ¿Podría alguien ayudarme a comprender esto?

Mi última pregunta es sobre el patrón abstracto de fábrica (o incluso el método de fábrica). Estos patrones de fábrica y el patrón de prototipo parecen intentar ocultar implementaciones concretas al crear nuevos objetos. ¿Cuándo es una buena idea elegir uno de los otros?

¡Gracias a todos!


La ganancia en eficiencia de usar un prototipo es cuestionable en mi mente. No habrá ganancia de eficiencia porque en la mayoría de los lenguajes el método clon mismo ejecuta una llamada a new para construir una nueva instancia de objeto de sí mismo.

El único beneficio que veo al usar el patrón de prototipo es de conveniencia, usted sabe que el clon le dará una copia exacta del objeto que lo libera de tener que establecer los atributos del nuevo objeto con los mismos valores y posiblemente tenga problemas con copia profunda


Tienes el patrón del prototipo correcto a la vista.

Cómo Reduce las Subclases

Digamos que estás haciendo Minecraft y estás usando el patrón de prototipo para cada tipo diferente de bloque (por ejemplo, tierra, piedra, etc.). Todos los objetos prototipo son en realidad del mismo Block clase, pero cada objeto tiene diferentes propiedades establecidas para que se vea y se comporte de manera diferente, por ejemplo:

prototypes.dirt = new Block; prototypes.dirt.texture = new Image("dirt.jpg"); prototypes.dirt.hardness = 1; prototypes.stone = new Block; prototypes.stone.texture = new Image("stone.jpg"); prototypes.stone.hardness = 9;

Entonces, en lugar de crear subclases donde escribirías un new DirtBlock o un new StoneBlock , en cambio escribirías prototypes.dirt.clone() o prototypes.stone.clone() . No se requieren subclases, pero aún tienes la opción de subclase si es necesario.

Diferencias con el patrón de fábrica

En cuanto a cuándo elegir el patrón de prototipo en lugar de un patrón de fábrica, hay dos situaciones en las que puedo pensar donde difieren:

  1. Puedes iterar sobre una lista de prototipos, pero no puedes iterar sobre todos los métodos en una fábrica abstracta ^. Continuando con el código anterior, puedes crear un bloque aleatorio como ese:

    prototypes.allValues().objectAtIndex(rand() % prototypes.size()).clone();

    Si estuviera usando el método de fábrica para hacer bloques, sería más difícil obtener un bloque aleatorio.

  2. Cuando la creación de un objeto es costosa, pero la copia es barata, el patrón del prototipo será más eficiente. Por ejemplo, tome este método de fábrica:

    Image loadUserImage() { //loads from disk. will be slow return new JPEGImage("path/to/user/image.jpg"); }

    Si se va a llamar repetidamente a este método, sería más eficiente usar un prototipo como ese:

    Image loadUserImage() { //copy in memory. will be fast return userImagePrototype.clone(); }

^ Esta es una mentira blanca porque en realidad puedes iterar sobre los métodos dependiendo del idioma que estés usando, pero iterar sobre una matriz probablemente sea una mejor solución porque es menos compleja que la reflexión / introspección.