Command

Warning: This post isn’t ready
I’m translating this:

Command

Problema: A la hora de llamar a funciones puede que te encuentres que quieres tratarlas como objetos para poder asignar mejor los parámetros y similares.

Solución: Con este patrón puedes encapsular una función como un objeto y poder tratarlo como tal.

Fundamento:


Básicamente, por cada función que quieras convertir en objeto, haces un comando concreto. Lo que sería la función puedes ponerla en operación y los parámetros como variables de esta clase. El resto del programa solo verá comandos por el polimorfismo y puedes cambiarlos como quieras.

Ejemplo:

Chain of Responsability

Warning: This post isn’t ready
I’m translating this:

Chain of Responsability

Problema: Imaginate que un objeto llama a una función de otro objeto, y este al hacer esto llama a otro objeto, y este a otro… cada uno con distintos nombres de funciones y tal. Como hemos visto hay soluciones para esto para facilitar el trabajar con esta clase de problemas.

Solución: Vamos a usar el polimorfismo para que las clases que heredan de una puedan llamar a otras facilmente y haciendo todo más estandarizado y fácil.

Fundamento:


Un manejador tendrá referencias de otros manejadores que dependan de el. Todos los manejadores tienen la función Operación (o la que sea) y al llamarla llaman también a los objetos asociados que puedan tener que hacerlo.

Ejemplo:

Proxy

Warning: This post isn’t ready
I’m translating this:

Proxy

Problema: Imaginate una interfaz, como el facade, pero que puedas cambiar para añadir flexibilidad (solo que la fachada solo se comunica con un solo objeto en vezde con varios).

Solución: Haciendo que las clases de fachada (aqui llamadas proxy) y las que hacen el trabajo hereden del mismo interfaz, hace que puedas cambiar de clase que realiza el trabajo en tiempo real y sin problemas.

Fundamento:



Ejemplo:

Flyweight

Warning: This post isn’t ready
I’m translating this:

Flyweight

Problema: Se usa demasiada memoria en tu proyecto y buscas formas de optimizar

Solución: El flyweight reduce el impacto en memoria de tu programa al compartir un objeto entre varios otros para no tener que hacer cientos o miles de copias de este con información idéntica. Por ejemplo, imagina una simulación sobre un hormiguero. No es factible crear millones de copias de un objeto con la misma información.

Fundamento:


En el programa existe una factoría flyweight (que debería ser además singleton para poder llamarla desde cualquier sitio) que lo que hace realmente es almacenar todos los objetos flyweight que se han creado y lo que hace es que si el objeto existe, te lo devuelve. El objeto puede ser compartido o no, eso da igual, pero si en dos objetos distintos necesitas usar el mismo objeto, con el flyweight factory recibes el mismo objeto y no tienes que crearte dos objetos distintos con los mismos valores para hacer lo mismo.

Ejemplo:

Facade

Warning: This post isn’t ready
I’m translating this:

Facade

Problema: Has hecho un montón de clases para un programa con un fin, por ejemplo, hacer gráficas a partir de unas tablas. Y decides poner el código on-line para que cualquiera lo baje (o es parte de un programa mayor) y quieres que se use bien, no que la gente se ponga a crear un objeto de una clase que no funciona bien sola.

Solución: Hacemos una interfaz que simplifique al usuario todo lo que hay detrás. El usuario no tiene que saber que para hacer una gráfica usas ciertos patrones, ciertas clases y tal… El lo que quiere es saber que clase llamar, y dentro de esa clase que funciones usar, para simplemente hacer una gráfica y olvidarse.

Vamos, lo que hemos estado haciendo hasta ahora al hacer cosas privadas o publicas.

Fundamento:


El objeto que haga de Facade sirve de interfaz para usar un sistema. Por ejemplo, para hacer una calculadora las funciones del facade serían sumar, restar, multiplicar, dividir, exponencial… Y al usuario le da igual lo que haya detras, solo sabe que llama a la función, mete dos numeros, y recibe otro.

Ejemplo:

Decorator

Warning: This post isn’t ready
I’m translating this:

Decorator

Problema: Vale, tenemos familias de objetos organizados con el Composite. Pero… ¿Y si lo que quiero es dinámicamente (en mitad de la ejecución) cambiar el comportamiento de un objeto?

Solución: Así es como sale este patrón, que no es más que hacer abstracto al composite para que así se pueda sustituir cualquier miembro de la familia en tiempo de ejecución sin problemas.

Fundamento:



Existe la interfaz Componente. Cada objeto que hereda de él es o bien un componente concreto o bien un decorador. Y si es un decorador significa que puede en un momento dado ejecutar la funcion „operacion“ de un decorador concreto, mientras que 5 minutos mas tarde se ha cambiado el decorador y el programa no tiene porque saberlo, llama a la misma función pero el programa hace otra cosa.

Ejemplo:

Composite

Warning: This post isn’t ready
I’m translating this:

Composite

Problema: Tienes una familia de objetos y buscas una buena forma de organizarlos.

Solución: Con este patron organizas objetos complejos a partir de unir simples de forma recursiva pero al usar la abstracción haces que todos tengan una interfaz común, lo cual es bueno para saber como usar a esa familia de objetos.

Fundamento:



Tenemos la interfaz Componente. Todos los objetos que heredan de esto son o bien composite si tienen más objetos „colgando de el“ (con la operación añadir) o hojas si no tienen hijos. Realmente esto acaba teniendo estructura de arbol (mira el siguiente capitulo sobre estructuras de datos para saber mas)

Ejemplo: Vamos a hacer una pequeña agenda telefónica de personas pero con un giro. En cada persona estarán colgadas las personas a las que conozca. Las personas serán composites y cada persona tendrá una serie de personas colgando de él (y puede haber repeticiones, haciendo que una persona enlace a quien la conoció y que puedas entrar en un bucle, el que pueda haber bucles hará que no automaticemos la busqueda, aunque si quieres intentarlo tendrás que hacer un control que detecte que lleva 3-4 veces saltando entre los mismos. Por ejemplo, prueba a añadir un booleano que diga si el objeto ha sido ya mostrado)

Bridge

Warning: This post isn’t ready
I’m translating this:

Bridge

Problema: Tienes una abstracción (una generalización, una clase que hereda de otra y tal). Y quieres modificarla reduciendo al mínimo las modificaciones en el resto del código, solo en la abstracción o su implementación.

Solución: La solución es algo parecida a lo anterior. Si separamos de una clase su implementación, hacemos que en el resto del programa se use la clase sin problemas ,y a la hora de modificar se use solo la clase que sea, pero no el resto.

Fundamento:



Ejemplo:

Adaptator

Warning: This post isn’t ready
I’m translating this:

Adaptador

Problema: Tienes una o varias clase que llama/usa funciones de otras clases. Si modificas estas clases usadas (nombre de función, qué devuelve…), entonces tienes que buscar y cambiar a lo largo de todo el código para dejarlo todo bien.

Solución: Crear una clase abstracta llamada „adaptador“ con una función llamada solicitud. Al resto del programa le dará igual como funcionen las clases que especifiquen esto, puesto que solo llamará a la función request. Luego esta función usará las clases que sean y pedirá los datos que sean, pero solo reduce las modificiaciones a dos clases y no a todo el programa.

Fundamento:



Ejemplo:

Singleton

Warning: This post isn’t ready
I’m translating this:

Singleton

Problema: ¿Quieres hacer un objeto que sea único, que no pueda haber copia de él, y que lo puedas llamar y usar desde cualquier parte del programa? Entonces necesitas un Singleton.

Solución: El singleton es una clase que realmente no la creas, pides una instancia de él. Al hacerlo, si no existía el objeto, este se crea a sí mismo y se asegura que las proximas veces que pidas una instancia de él solo venga él. Y al ser static puedes llamar a la instancia en cualquier sitio del programa. ¿Algunos usos útiles? Para hacer informes del programa. Haces una clase que incorpore las funciones y variables del singleton, y haces que por cada fallo o cosa a registrar, se llame a esta clase para que lo registre. Así desde cualquier parte del programa se puede escribir una linea de texto en el archivo final.

Fundamento:


Al llamar a la funcion estática getInstancia(), la funcion mira si InstanciaUnica tiene algún valor o no. Si no tiene ningún valor asignado, es la primera vez que se llama la función, así que llama al constructor y guarda el nuevo singleton en instancia unica. Al final devuelve el valor que esté en instancia única.

Ejemplo:

Prototype

Warning: This post isn’t ready
I’m translating this:

Prototype

Problema: Quieres un objeto, pero que no sea nuevo, si no un clon de otro ya existente. Por ejemplo, para hacerle cambios al clon pero que no afecten al original (hacer un prototipo)

Solución: El prototipo tiene como ventajas que te ahorra el tener que hacer una fábrica para este tipo de objetos, pues al ser un clon de uno ya existente el esfuerzo de programación es muy bajo, y lo mismo se traduce al rendimiento: Si tienes que crear un objeto complejo, se requiere reservar mucha memoria y eso puede ir en contra del programa, pero si se usa un clon se agiliza.

Fundamento: Tenemos el interfaz prototipo. Todas las funciones que lo implementen heredarán de él la función clonar(), además al ser una función abstracta cada hijo lo especificará comole de la gana.



Ejemplo:

Factory Method

Warning: This post isn’t ready
I’m translating this:

Factory Method

Problema: Parecido al de la fábrica abstracta, tenemos que crear una familia de objetos. Pero en este caso no se esperan nuevas familias y las ya existentes estan categorizadas por cosas comunes (a diferencia de hacer una pizza, en la que los objetos masa y topping no tienen información en común).

Solución: Factory Method es otra simplificación de la fábrica abstracta. Esta se diferencia en que no se usan interfaces, si no que ya hay algunas funciones comunes definidas. Por ejemplo, un constructor para inicializar los datos comunes de las clases hijas.

Fundamento: El programa tiene un objeto de la clase fabrica abstracta, que según el producto específico a crear usará una especialización de este u otra. Recordemos que cada producto es una colección de objetos y con este patrón evitamos tener que estar creando a mano los nuevos objetos cada vez que queramos uno, reduciendo el riesgo de cometer errores.



Ejemplo:

Builder

Warning: This post isn’t ready
I’m translating this:

Builder

Problema: A la hora de de hacer un nuevo objeto, la cantidad de parámetros es larguísima, indicando que hemos cometido un fallo en el diseño (un anti-patrón, que parece una solución pero no es buena). Aparte de que con muchas opciones, el diseño puede no ser lo suficientemente flexible (y la falta de flexibilidad se soluciona con clases abstractas y polimorfismo).

Solución: Este es el patrón de construcción para crear nuevos objetos más sencillo que hay en esta lista (el singleton no cuenta). Permite configurar más fácilmente la creación de estos objetos, sin tener que memorizar una lista larga de parámetros en los constructores. Es util al crear objetos a partir de XML o similares. La diferencia con las fábricas es que las fábricas crean familias de objetos, pero el builder crea objetos complejos.

Fundamento:


Tenemos una clase director, que se configura a base de cambiar las variables, y al final se le da a construir para que genere un objeto del tipo que sea. Vamos a verlo en el ejemplo.

Ejemplo:

Imaginate que tenemos una cadena de hamburguesas (antes pizzas, ahora hamburguesas) y que queremos crear una pizza según lo que nos diga el cliente. Una opción sería hacer algo como:

public Menu pedirMenu(Hamburguesa burger, Refresco ref, Postre pos, Regalo reg);

Puede que tu tengas una memoria maginifica y sepas bien como va esto pero si se lo pasas a otro programador puede tener problemas. Así que para prevenir problemas y para tener las ventajas que ofrece esto (como que si cambia el menú no se cambia el resto del programa [en principio]), vamos a hacer el siguiente diseño:

Abstract Factory

Warning: This post isn’t ready
I’m translating this:

Abstract Factory

Problema: A la hora de crear objetos, resulta que tienes que crear no solo uno, si no varios, y configurarlos para que estén relacionados representando todo un grupo de clases. No es solo llamar al constructor de uno, que ese llame a otro y listo. Y se espera que en un futuro se añadan nuevas fábricas y tipos de producto. Si no entiendes bien esto ultimo mira el ejemplo, al final de él se explica lo de añadir nuevos sin modificar lo viejo.

Solución: Una clase especializada en construirte el sistema de clases listo y configurado según como se requiera. Aparte de que al tener el código de creación aparte puedes hacerlo estático para invocar la fábrica desde cualquier parte del código para crearte objetos.

Fundamento:


Es la primera vez que lees Interface. ¿Que es un interface? Es una clase sin variables en la que todas las funciones son abstractas. Lo que las hace especiales es que una clase puede heredar de solo una clase, pero puede heredar de todas las interfaces que quieras. En este caso no se llama heredar, si no implementar. Aunque es lo mismo.

Ejemplo: Vamos a realizar para el ejemplo un gestor de textos. El usuario crea un programa para gestionar pizzas. (Esta basado en el ejemplo de Headfirst. Me parece mejor ejemplo que el clásico de fabricar coches en el que los productos son puertas, carrocerías y ventanas, y en la fabrica se cogen esos)

En este caso, tenemos un gestor de pizzas que se encarga de fabricar pizzas (Debería ser más complejo e incorporar una clase Pizza para la información, pero para el ejemplo de fabrica abstracta nos vale). Las funciones escribir de los ingredientes nos servirán para saber que ingredientes tiene. La fabrica de pizzas modernas crea pizzas modernas (con salsa barbacoa y masa gruesa) mientras que la clasica crea pizzas más tradicionales de masa fina y jamón.

Ventajas de este diseño en este problema: Que si queremos añadir nuevos tipos de masa o nuevos tipos de topping… no hace falta modificar lo que ya esta hecho, es solo añadir, y así se evitan posibles fallos en el futuro: Se crea la clase ToppingHawaiana por ejemplo, que implemente Topping, y si eso se hace una nueva fabrica.


El código queda tal que así:

Interfaz Masa:

 

MasaFina:

 

MasaGruesa:

 

Interfaz Topping

 

Procciuto

 

Barbacoa

 

FabricaPizzasAbstracta

 

FabricaPizzasClasica

 

FabricaPizzasModernas

 

Gestor Pizzas

 

Ejecutando este ejemplo el resultado debería darte:

Software Design Patterns

I’m translating this:

Patrones de diseño

Ya que has aprendido lo básico de programación orientada a objetos realmente solo te falta por aprender:

  • Clases ya hechas en Java para no tener que programar algo que ya esta hecho y saber qué puedes usar en cada momento y que no. Lo reservo para un glosario al final del cursillo puesto que puedes comprobarlos en cualquier momento en el javadoc (manual de clases de Java https://docs.oracle.com/javase/8/docs/api/ . Estan catalogadas por paquetes. Un paquete es una colección de clases con un orden lógico dentro de un proyecto. Por ejemplo, yo en NetBeans dentro del proyecto „curso“ tengo un package por cada tema/proyecto del curso).
  • Patrones de diseño: Ante problemas comunes se usan soluciones típicas para cada uno. Los patrones de diseño son soluciones estándar y probadas ante cierto tipo de problemas. Una serie de clases que relacionadas de cierta forma y con ciertas funciones que hacen algo, te permiten realizar soluciones.
    • Estructuras de datos: Para muchos no son patrones de diseño pero entran en la descripción. Lo que lo diferencia respecto a los patrones de diseño es que sirven más como distintas formas de guardar los datos en vez de tratarlos.
  • Algoritmos: Te permiten resolver problemas de forma rápida y efectiva.

Vamos a ver los „originales“, los primeros en salir y más tarde veremos otros mas modernos:

Creacionales (crean objetos o dicen como son)

  • Abstract Factory
  • Builder
  • Factory Method
  • Prototype
  • Singleton

Estructurales (Resuelven problemas composición de clases y objetos)

  • Adaptador
  • Bridge
  • Composite
  • Decorator
  • Facade
  • Flyweight
  • Proxy

De comportamiento (solucionan problemas sobre cómo interactúan entre sí los objetos)

  • Chain of Responsability
  • Command
  • Interpreter
  • Iterator
  • Mediator
  • Memento
  • Observer
  • State
  • Strategy
  • Template method
  • Visitor