Mostrando entradas con la etiqueta diseño. Mostrar todas las entradas
Mostrando entradas con la etiqueta diseño. Mostrar todas las entradas

miércoles, 9 de marzo de 2016

Patrones de diseño

Que son los Patrones de Diseño ?

Volviendo a las labores, esté será el inicio de una serie de entradas sobre los patrones de diseño, en esta ocasión vamos a ver conceptos en general para responder preguntas como por ejemplo ¿que son?, ¿cual es su aplicación en el desarrollo de software?, problemas y soluciones que brindan...........mencionaremos algunos de los patrones mas usados y daremos paso a próxima entradas con ejemplos Java....

No vamos a entrar en detalle sobre datos históricos, creadores o profundizar mucho sobre alguno de los patrones, tocaremos lo básico que debemos saber para trabajar con estos, en otros artículos intentaré dar ejemplos de cada uno..............Empecemos!!!!

¿Que Son? 

Los Patrones de diseño son herramientas para solucionar problemas de Diseño enfocados al desarrollo de software, estos patrones deben ser reusables permitiendo así que sean adaptados a diferentes problemáticas.

Cuando hablamos de problemáticas nos referimos a condiciones o problemas reiterativos en el desarrollo de software donde la solución se encuentra identificada mediante la aplicación de una serie de pasos, adaptando el sistema a una estructura definida por un patrón, garantizando que esta solución pueda ser aplicada cuantas veces sea necesario en circunstancias similares, evitando así la búsqueda de otras soluciones cuando estas ya se han dado anteriormente...

Existen 3 grupos de patrones:
  • Creacionales: Giran en torno a la creación de Objetos
  • Estructurales: Se enfocan en la estructura de clases y objetos que las componen
  • De Comportamiento: Definen el modo en que las clases y objetos son relacionados, el comportamiento he interacción entre ellos. 

Algunos Patrones.

Vamos a ver algunos de los principales patrones de diseño, daremos una pequeña descripción en torno al problema y la solución................mas adelante realizaremos algunos ejemplos de aplicación.

Modelo Vista Controlador (MVC)
Es un patrón estructural que permite separar la información y lógica de negocio de la parte visual de la aplicación y la lógica que gestiona las relaciones y eventos del sistema. (Ver Ejemplo...)
Problema : Cuando tenemos código que no es fácilmente controlado o mantenible, debido a que tenemos muchas funcionalidades en una sola clase y principalmente cuando queremos dar una representación visual pero al tener todo centralizado no se puede realizar con eficacia.
Solución: Se aplica el MVC donde reestructuramos nuestro código fuente separándolo en 3 partes funcionales con comportamientos definidos que posteriormente son relacionadas entre si, facilitando la mantenibilidad y flexibilidad del código, estas 3 partes son el Modelo, la Vista y el Controlador.
  • Modelo : Representa la información y los datos procesados por el sistema, gestionando la forma como se accede a estos y la lógica de negocio de la aplicación. 
  • Controlador : Representa el puente de interacción entre el Modelo y la Vista, define la forma como se relacionan los componentes de la aplicación. 
  • Vista : Es la representación del modelo mediante una interfaz gráfica de usuario, es la forma como el usuario interactúa con el sistema, permitiendo la ejecución de eventos he ingreso de información que serán procesados por el Modelo.

Observer

Es un patrón de comportamiento permite actualizar automáticamente el estado de un objeto dependiendo del estado de un objeto principal, cuando el objeto principal cambia sus objetos dependientes se actualizan.(Ver Ejemplo)


Problema : Cuando tenemos una dependencia de 1 a muchos entre objetos, y se espera que cuando el estado de un objeto cambie, todos los objetos dependientes de este también cambien de forma automática, por ejemplo se tiene una aplicación de venta de productos administrada por diferentes vendedores con diferentes aplicativos (web, escritorio, móvil), se espera que cada vez que cambie la cantidad de productos disponibles, la aplicación de cada vendedor automáticamente actualicé el modulo de ventas con los nuevos valores sin necesidad de recargar la página o actualizar manualmente el sistema para que muestre los cambios.
Solución: Se aplica el patrón observador para desacoplar la clase que contenga objetos dependientes, estableciendo relaciones entre los objetos, para esto se tiene una clase SujetoConcreto que sera el objeto principal y tendremos los objetos cliente o dependientes que serian de clase ObservadorConcreto, cuando el estado del SujetoConcreto cambia, se envía una señal a cada uno de sus Observadores y estos automaticamente cambian su estado basados en el estado del objeto principal.



Value Object (VO)

Consiste básicamente en la agrupación de datos dentro de un objeto, estos datos representan los campos de una tabla o entidad de la BD y facilitan su mantenimiento y transporte dentro del sistema. (Ejemplo con MySql)


Problema : Al momento de pasar argumentos de un objeto a un método puede ocasionar que el método reciba gran cantidad de datos pasados como parámetros, si posteriormente se requiere la modificación de uno de esos argumentos se obliga a que todos los métodos que reciban estos argumentos sean cambiados, presentándose problemas de acoplamiento y mantenibilidad.
Solución: Se crean clases que representan las tablas de la BD que utiliza el sistema, de esta manera las propiedades o atributos de la clase serán los campos de la entidad, permitiendo encapsular la información y facilitando la manera en que estos son transportados, así al momento de enviar los parámetros a un método, se envía un solo objeto que los contiene.


Data Access Object (DAO) 

Facilita y estructura el acceso a la información de una Base de Datos, separando la persistencia de objetos de la lógica de acceso a datos, brindando mayor flexibilidad ya que por ejemplo al momento de hacer un cambio en la lógica de negocio, esto seria transparente para la lógica de acceso a la información. (Ejemplo con MySql)

Problema : Se tienen diferentes implementaciones para el acceso a datos, de esta manera al cambiar el proveedor de  BD o la forma de conexión puede afectar la manera de acceder a los datos teniendo que implementar nuevamente el proceso en todos los componentes vinculados.
Solución: Se utilizan clases DAO para encapsular todos los accesos a la fuente de datos desacoplando de esta manera la lógica de negocio de la lógica de acceso a datos, estableciendo mayor organización y facilitando la mantenibilidad y extensibilidad del código fuente.


Delegate.

Permite extender y reutilizar la funcionalidad de una clase sin utilizar el mecanismo de herencia. (Ver Ejemplo)


Problema : Se requiere el acceso a atributos de otras clases pero estos no se pueden heredar, ya que el lenguaje no permite la herencia múltiple o solo se quiere acceder a cierta información de la clase (La clase A no desea todos los métodos de la clase B)
Solución: Se utiliza el patrón Delegate reemplazando la relación "Es Un" por la relación "Usa" delegando la responsabilidad de ejecutar un proceso concreto usando otro objeto con los permisos para realizarlo, esto se hace por medio de conceptos como la composición o agregación.


Abstract Factory 

Representa una fabrica de objetos, permitiendo la construcción de familias de objetos, es decir tipos de objetos con el mismo enfoque o relaciones. (Ver Ejemplo)


Problema : Se requiere la creación de diferentes grupos de objetos, sin que se especifique la forma de hacerse, el cliente (la clase que ejecute el evento de creación) que solicite el objeto no necesita saber como se creará, este proceso deberá ser transparente para el, el cliente solo requiere una instancia de alguno de los grupos de objetos disponibles.

Solución: Se utiliza el patrón Abstract Factory para independizar la manera como se crearán los objetos concretos de forma que sea independiente de la clase que los solicita, por ejemplo si queremos crear un objeto hamburguesa podemos usar el patrón para definir familias de Hamburguesas agrupándolas por hamburguesas McDonald´s, Wendy´s y Texas, sin importar el tipo siempre se creara un objeto 
hamburguesa pero con las características propias de cada grupo de familia disponible.


Singleton 

Permite la creación de una única instancia de clase permitiendo que sea global para toda la aplicación. (Ver Ejemplo)


Problema : Se debe restringir la creación de un tipo especifico de objetos a una única instancia garantizando un punto único de acceso para todo el sistema.
Solución: Se utiliza el patrón Singleton como mecanismo para limitar el numero de instancias de la clase, compartiendo la misma instancia por diferentes objetos del sistema, obteniendo una variable global para toda la aplicación.


Decorator 

Este patrón permite agregar funcionalidades o responsabilidades a objetos de forma transparente y dinámica, sin ser dependiente de la herencia en su totalidad. (Ver Ejemplo)

Problema :Cuando se quiere adherir responsabilidades o comportamientos específicos a un objeto pero de forma dinámica, es decir, permitiendo al usuario aplicar el comportamiento que desea, extendiendo funcionalidades de otras clases sin estar obligado a hacerlo mediante la herencia.
Solución: Se utiliza el patrón Decorator para adherir funcionalidades a un objeto implementando y creando relaciones con otras clases para incorporar dichas funcionalidades de forma dinámica, por ejemplo si tenemos una clase ventana, podemos usar el patrón para adherir otros comportamientos como por ejemplo darle estilos a la ventana, diferentes colores, bordes, tamaño, marco, entre otros componentes que deseamos vincular, los cuales se encuentran en diferentes clases.

 
Adapter. 

Permite la cooperación entre clases para extender sus funcionalidades a clases de diferentes tipos, que no pueden usarlas por mecanismos comunes como la herencia. (Ver Ejemplo)




Problema : Cuando se quiere utilizar una clase existente, pero su interfaz no es compatible o no esta relacionada con la clase que la va a utilizar.
Solución: Utilizando el patrón Adapter podemos relacionar clases incompatibles entre si, generando un mecanismo que permita extender su comportamiento por medio de una clase puente que sirva como interfaz entre la clase en cuestión y el resto de clases que quieran hacer uso de sus funcionalidades.


Conclusiones.

Como vimos los patrones de diseño nos permiten dar soluciones a  diferentes problemáticas comunes, algunas simples otras con mayor grado de complejidad, no siempre es necesario usar estos patrones sin embargo se recomienda su aplicación para buscar siempre un sistema mas optimo y con una arquitectura definida, cual o cuales aplicar depende de las necesidades del sistema.

Estos son algunos de los Patrones mas usados, existen muchos mas pero por cuestiones de organización y tamaño vamos a ver si se pueden exponer mas adelante, por el momento esta información nos sirve para dar un contexto base de lo que son y las posibles soluciones que brindan, en la próximas entradas trabajaremos cada uno de ellos mediante un ejemplo practico...


Referencias.

Head First Design Patterns
http://codejavu.blogspot.com.uy/2013/06/que-son-los-patrones-de-diseno.html

Patron de diseño Observer

As the name suggests it is used for observing some objects.Observer watch for any change in state or property of subject.Suppose you are interested in particular object and want to get notified when its state changes then you observe that object and when any state or property change happens to that object,it get notified to you.

As described by GoF:
"Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically".

You can think of observer design pattern in two ways
  • Subject-Observer relationship:Object which is being observed is refereed as Subject and classes which observe subject are called Observer 
  • Publisher-Subscriber relationship:A publisher is one who publish data and notifies it to the list of subscribers who have subscribed for the same to that publisher. A simple example is Newspaper. Whenever a new edition is published by the publisher,it will be circulated among subscribers whom have subscribed to publisher.
The observers will not monitor every time whether there is any change in state of subject or not, since they will be notified for every state change of subject, until they stop observing subject. So it follows hollywood principle-"Don't call us,we will call you".

    Some real life examples:

    You might have surfed "Flipkart.com-Online megastore".So when you search for any product and it is unavailable then there is option called "Notify me when product is available".If you subscribe to that option then when state of product changes i.e. it is available,you will get notification mail "Product is available now you can buy it".In this case,Product is subject and You are an observer.

    Lets say,your permanent address is changed then you need to notify passport authority and pan card authority.So here passport authority and pan card authority are observers and You are a subject.

    On facebook also,If you subscribe someone then whenever new updates happen then you will be notified. 

    When to use it:

    • When one object changes its state,then all other dependents object must automatically change their state to maintain consistency
    • When subject doesn't know about number of observers it has.
    • When an object should be able to notify other objects without knowing who objects are.

     UML diagram for observer design pattern:

    Components:

    Subject

    • Knows its observers
    • Has any number of observer
    • Provides an interface to attach and detaching observer object at run time
    Observer
    • Provides an update interface to receive signal from subject
    ConcreteSubject
    • Stores state of interest to ConcreteObserver objects.
    • Send notification to it's observer
    ConcreteObserver
    • Maintains reference to a ConcreteSubject object
    • Maintains observer state consistent with subjects.
    • Implements update operation

    Java in-built API for observer pattern: 

    The java API provides one class and one inteface for implementing observer pattern.
    1. java.util.Observable-class
    2. java.util.Observer-interface

    java.util.Observable: 

    For being observed,class must extend this class. The subclass becomes observable and override methods of  java.util.Observable and other objects can "observe" changes in state of this object.
    Methods:
    addObserver(Observer o) :add Observer to the list of observers for this subject.
    deleteObserver(Observer o) :delete Observers from the list of observers .
    notifyObservers() : notify all the observers if object has changed.
    hasChanged() :return true if object has changed.
    setChanged() :This method marks object has changed
    clearChanged() :this method will indicate that subject has no changes or all the observers has been notified.

    java.util.Observer: 

    The class that performs the "observing" must implement the java.util.Observer interface. There is a single method: 
    public void update(Observable obj, Object arg) :This method is called whenever the observed object is changed. An application calls an Observable object's notifyObservers method for notifying to all the observers of change.

      Example: 

      You might have surfed "Flipkart.com-Online megastore".So when you search for any product and it is unavailable then there is option called "Notify me when product is available".If you subscribe to that option then when state of product changes i.e. it is available,you will get notification mail "Product is available now you can buy it".

      Java code:

      Below interface is our subject interface.It consists of method for adding or removing observers and also in condition of state change,notify all observer. 

      1.Subject.java:

      1. package org.arpit.javapostsforlearning;  
      2.   
      3. public interface Subject {  
      4.      public void registerObserver(Observer observer);  
      5.      public void removeObserver(Observer observer);  
      6.      public void notifyObservers();  
      7. }  

      Below class is our ConcreteSubject class.It implements subject interface thus provide implementation of all above three methods.  

      2.Product.java:

      1. package org.arpit.javapostsforlearning;  
      2.   
      3. import java.util.ArrayList;  
      4.   
      5. public class Product implements Subject{  
      6.   
      7.     private ArrayList<Observer> observers = new ArrayList<Observer>();  
      8.     private String productName;  
      9.     private String productType;  
      10.     String availability;  
      11.       
      12.       
      13.     public Product(String productName, String productType,String availability) {  
      14.         super();  
      15.         this.productName = productName;  
      16.         this.productType = productType;  
      17.         this.availability=availability;  
      18.     }  
      19.       
      20.     public ArrayList<Observer> getObservers() {  
      21.         return observers;  
      22.     }  
      23.     public void setObservers(ArrayList<Observer> observers) {  
      24.         this.observers = observers;  
      25.     }  
      26.     public String getProductName() {  
      27.         return productName;  
      28.     }  
      29.     public void setProductName(String productName) {  
      30.         this.productName = productName;  
      31.     }  
      32.     public String getProductType() {  
      33.         return productType;  
      34.     }  
      35.     public void setProductType(String productType) {  
      36.         this.productType = productType;  
      37.     }  
      38.       
      39.     public String getAvailability() {  
      40.         return availability;  
      41.     }  
      42.   
      43.     public void setAvailability(String availability) {  
      44.         this.availability = availability;  
      45.         notifyObservers();  
      46.     }  
      47.   
      48.     public void notifyObservers() {  
      49.         System.out.println("Notifying to all the subscribers when product became available");  
      50.          for (Observer ob : observers) {  
      51.              ob.update(this.availability );  
      52.       }  
      53.   
      54.     }  
      55.   
      56.     public void registerObserver(Observer observer) {  
      57.          observers.add(observer);  
      58.           
      59.     }  
      60.   
      61.     public void removeObserver(Observer observer) {  
      62.          observers.remove(observer);  
      63.           
      64.     }  
      65.   
      66. }  

       Below interface is our observer interface.It consists of single method called "update"

      3.Observer.java:

      1. package org.arpit.javapostsforlearning;  
      2. public interface Observer {  
      3.       public void update(String availability);  
      4. }  

      Below class is our ConcreteObserver class.It implements observer interface and provide implementation for update and other ConcreteObserver specific methods.

      4.Person.java:

      1. package org.arpit.javapostsforlearning;  
      2. public class Person implements Observer{  
      3.   
      4.     String personName;  
      5.   
      6.     public Person(String personName) {  
      7.         this.personName = personName;  
      8.     }  
      9.   
      10.     public String getPersonName() {  
      11.         return personName;  
      12.     }  
      13.   
      14.     public void setPersonName(String personName) {  
      15.         this.personName = personName;  
      16.     }  
      17.   
      18.     public void update(String availabiliy) {  
      19.           
      20.         System.out.println("Hello "+personName+", Product is now "+availabiliy+" on flipkart");  
      21.     }  
      22. }  

      5.ObserverPatternMain.java:

      1. package org.arpit.javapostsforlearning;  
      2. public class ObserverPatternMain {  
      3.   
      4.     /** 
      5.      * @Author arpit mandliya 
      6.      */  
      7.     public static void main(String[] args) {  
      8.         Person arpitPerson=new Person("Arpit");  
      9.         Person johnPerson=new Person("John");  
      10.           
      11.         Product samsungMobile=new Product("Samsung", "Mobile", "Not available");  
      12.           
      13.         //When you opt for option "Notify me when product is available".Below registerObserver method  
      14.         //get executed          
      15.         samsungMobile.registerObserver(arpitPerson);  
      16.         samsungMobile.registerObserver(johnPerson);  
      17.           
      18.         //Now product is available  
      19.         samsungMobile.setAvailability("Available");  
      20.           
      21.     }  
      22. }  

      Run it:

      1. Notifying to all the subscribers when product became available  
      2. Hello Arpit, Product is now Available on flipkart  
      3. Hello John, Product is now Available on flipkart  
      Now in above program,when availability of samsung mobile changes,it get notified subscribers who has subscribed for it.

      Using java inbuilt APIs: 

      1.Product.java:

      1. package org.arpit.javapostsforlearning;  
      2. import java.util.ArrayList;  
      3. import java.util.Observable;  
      4. import java.util.Observer;  
      5.   
      6. public class Product extends Observable{  
      7.    
      8.    private ArrayList<Observer> observers = new ArrayList<Observer>();  
      9.     private String productName;  
      10.     private String productType;  
      11.     String availability;  
      12.       
      13.       
      14.     public Product(String productName, String productType,String availability) {  
      15.         super();  
      16.         this.productName = productName;  
      17.         this.productType = productType;  
      18.         this.availability=availability;  
      19.     }  
      20.       
      21.     public ArrayList<Observer> getObservers() {  
      22.         return observers;  
      23.     }  
      24.     public void setObservers(ArrayList<Observer> observers) {  
      25.         this.observers = observers;  
      26.     }  
      27.     public String getProductName() {  
      28.         return productName;  
      29.     }  
      30.     public void setProductName(String productName) {  
      31.         this.productName = productName;  
      32.     }  
      33.     public String getProductType() {  
      34.         return productType;  
      35.     }  
      36.     public void setProductType(String productType) {  
      37.         this.productType = productType;  
      38.     }  
      39.       
      40.     public String getAvailability() {  
      41.         return availability;  
      42.     }  
      43.   
      44.     public void setAvailability(String availability) {  
      45.         if(!(this.availability.equalsIgnoreCase(availability)))  
      46.         {  
      47.             this.availability = availability;  
      48.             setChanged();  
      49.             notifyObservers(this,availability);  
      50.         }  
      51.     }  
      52.   
      53.     public void notifyObservers(Observable observable,String availability) {  
      54.         System.out.println("Notifying to all the subscribers when product became available");  
      55.          for (Observer ob : observers) {  
      56.              ob.update(observable,this.availability);  
      57.       }  
      58.   
      59.     }  
      60.   
      61.     public void registerObserver(Observer observer) {  
      62.          observers.add(observer);  
      63.           
      64.     }  
      65.   
      66.     public void removeObserver(Observer observer) {  
      67.          observers.remove(observer);  
      68.           
      69.     }  
      70. }  
      71.   
      72.    
      2.Person.java 

      1. package org.arpit.javapostsforlearning;  
      2. import java.util.Observable;  
      3. import java.util.Observer;  
      4.   
      5. public class Person implements Observer{  
      6.   
      7.     String personName;  
      8.       
      9.       
      10.     public Person(String personName) {  
      11.         this.personName = personName;  
      12.     }  
      13.   
      14.   
      15.     public String getPersonName() {  
      16.         return personName;  
      17.     }  
      18.   
      19.   
      20.     public void setPersonName(String personName) {  
      21.         this.personName = personName;  
      22.     }  
      23.   
      24.     public void update(Observable arg0, Object arg1) {  
      25.         System.out.println("Hello "+personName+", Product is now "+arg1+" on flipkart");  
      26.           
      27.     }  
      28.   
      29. }  

      3.ObserverPatternMain.java:

      1. package org.arpit.javapostsforlearning;  
      2. public class ObserverPatternMain {  
      3.   
      4.     /** 
      5.      * @Author arpit mandliya 
      6.      */  
      7.     public static void main(String[] args) {  
      8.         Person arpitPerson=new Person("Arpit");  
      9.         Person johnPerson=new Person("John");  
      10.           
      11.         Product samsungMobile=new Product("Samsung", "Mobile", "Not available");  
      12.           
      13.         //When you opt for option "Notify me when product is available".Below registerObserver method  
      14.         //get executed      
      15.         samsungMobile.registerObserver(arpitPerson);  
      16.         samsungMobile.registerObserver(johnPerson);  
      17.           
      18.         //Now product is available  
      19.         samsungMobile.setAvailability("Available");  
      20.            
      21.     }  
      22. }  

      Run it:

      1. Notifying to all the subscribers when product became available   
      2. Hello Arpit, Product is now Available on flipkart  
      3. Hello John, Product is now Available on flipkart  

      Some important points about observer pattern:

      • Loose coupling between Subject and Observer:Only thing subject know about its observers is that observer implements Observer interface.You can register or delete any observer without affecting subject. 
      • Support for broadcast communication:Notification about subject state change does not need to specify its receiver.This notification is broadcasted to all interested object that subscribed to it.
      • The one of the problem with this pattern is that debugging become very hard,if you have large number of subscribers because flow of control is implicit between subject and observers.
      • Spurious updates:If criteria for state change is not well defined then sometimes it lead to spurious updates.

      Read more at http://www.java2blog.com/2013/02/observer-design-pattern-in-java.html#JEiroupV5sfwIsYQ.99