Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Design patters corrections #16

Open
wants to merge 9 commits into
base: master
Choose a base branch
from

Conversation

lnfrative
Copy link

Patrones creacionales

Builder

Problema: La clase Invoice es compleja con una gran cantidad de parámetros en su constructor. Esto dificulta la creación de estos objetos y condiciona a tener todos los parámetros que necesita la clase antes de su creación.

Solución e implicaciones: Utilizando el patrón creacional Builder, se crea una interfaz genérica Builder que contenga el método build(). Esta interface será implementada por InvoiceBuilder, que permitirá crear objetos Invoice de manera dinámica y sin necesidad de tener todos los parámetros que requiere la clase al momento de su instalación.

image

Singleton

Problema: Employee es la clase que representa al empleado que está utilizando el programa, sea administrador o personal normal. Este empleado es único debido a que se crea durante el login después de que el usuario añade correctamente sus credenciales. Tener diferentes instancias del mismo Employee en toda la aplicación puede comprometer la integridad de los datos de Employee.

Solución e implicaciones: Mediante el patrón creacional Singleton, se busca tener una única instancia de la clase Employee en toda la aplicación. La solución más óptima consistió en crear una clase AppState que contenga el atributo de tipo Employee con sus respectivos getters y setters. Esta clase AppState es instanciada durante la inicialización de la aplicación en la clase MainApp.

La referencia de AppState se pasa a través de los controladores de la aplicación para que puedan tener acceso a la instancia. Se creó una interface Controller que todo controlador debe implementar y que tiene como método setAppState(), de manera que todo controlador acepte la referencia de AppState.

image

Factory Method

Problema: Product es una clase muy global que con el tiempo puede crecer y volverse difícil de mantener. Al extraer la funcionalidad no esencial hacia clases hijas, se crean clases derivadas de Product que vuelve difícil la creación de un producto según sus diferentes tipos.

Solución e implicaciones: Haciendo uso del patrón creacional Factory Method se buscó poder crear instancias de todo tipo de productos a través de la delegación de clases de fabrica o factorías. Estas clases de fábrica extienden de ProductFactory que representa la clase abstracta que dicta la creación de un producto genérico. Cada una de las diferentes factorías para cada tipo de producto específico extiende de esta clase ProductFactory y añade métodos y atributos adicionales en caso de necesitar para poder crear el respectivo producto.

image

Patrones estructurales

Adapter

Problema: Existe una relación de funcionalidad parcial entre las clases Product e Item, pero cada uno extiende de interfaces diferentes no compatibles. Para evitar el código repetido en algunas partes del proyecto, se busca que estas clases sean compatibles e interoperables.

Solución e implicaciones: Haciendo uso del patrón estructural Adapter, se crea una clase ItemAdapter para que un Ítem pueda obtener la funcionalidad de Product en caso de requerirse. En esta solución, ItemAdapter no implementa directamente a Product sino que extendió de ProductBase aprovechando que se había creado en la solución del patrón Builder. De esta manera, un ItemAdapter puede comportarse completamente como un Product recibiendo un Item.

image

Facade

Problema: Product es una clase que se presta a tener muchas instancias durante toda la aplicación, además de los diferentes tipos de clases hijas que posee. No existe en el proyecto una manera centralizada de manejar una colección de productos cuando se requiera hacer uso de estos, como al mostrar el inventario por ejemplo.

Solución e implicaciones: El patrón Facade nos permite reducir la complejidad del manejo de productos a través de una interfaz que podamos proveer al cliente. Por esta razón, se creó una interfaz ProductManager que representa la funcionalidad que implica el manejo de productos en la aplicación. La clase que utilizará el cliente para implementar esta funcionalidad será ProductManagerFacade.

image

Decorator

Problema: Existen características para Product que puede ser opcional o no en todos los casos requerirse. Se necesita implementar parte de esta funcionalidad sin que se tenga que modificar las clase Product por sí misma concretamente para añadir la posibilidad de que un producto tenga un descuento. Actualmente, descuento es una propiedad que se da en Invoice, pero no necesariamente un descuento aplica a toda una factura sino a productos específicos.

Solución e implicaciones: Esto se puede lograr haciendo uso de el patrón estructural Decorator. Se creó una clase abstracta ProductDecorator que implementa a Product pero que recibe una instancia de product en su constructor. De esta manera, se pueden crear todo tipo de decoradores para Product, no solo un descuento.

Se creo una clase Descuento que extienda de ProductDecorator. Descuento tiene la funcionalidad de Product pero añade el atributo descuento y modifica el precio para entregarlo con el descuento calculado. Ahora cuando se necesite calcular el precio de un producto que posee un descuento solo se necesita hacer uso de este decorador y llamar al método getPrice.

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant