Sunteți pe pagina 1din 46

Factory Method (patrn de diseo)

En diseo de software, el patrn de diseo Factory Method consiste en utilizar una clase constructora (al estilo del Abstract Factory) abstracta con unos cuantos mtodos definidos y otro(s) abstracto(s): el dedicado a la construccin de objetos de un subtipo de un tipo determinado. Es una simplificacin del Abstract Factory, en la que la clase abstracta tiene mtodos concretos que usan algunos de los abstractos; segn usemos una u otra hija de esta clase abstracta, tendremos uno u otro comportamiento.

Estructura[editar editar cdigo]


Las clases principales en este patrn son el creador y el producto. El creador necesita crear instancias de productos, pero el tipo concreto de producto no debe ser forzado en las subclases del creador, porque las posibles subclases del creador deben poder especificar subclases del producto para utilizar.

La solucin para esto es hacer un mtodo abstracto (el mtodo de la fbrica) que se define en el creador. Este mtodo abstracto se define para que devuelva un producto. Las subclases del creador pueden sobrescribir este mtodo para devolver subclases apropiadas del producto...

Ejemplo de cdigo (en Java)[editar editar cdigo]


abstract class Creator{ // Definimos mtodo abstracto public abstract Product factoryMethod(); } Ahora definimos el creador concreto. public class ConcreteCreator extends Creator{ public Product factoryMethod() { return new ConcreteProduct(); }

} Y definimos el producto y su implementacin concreta. public interface Product{ public void operacion(); } public class ConcreteProduct implements Product{ public void operacion(){ System.out.println("Una operacin de este producto"); } } Y un ejemplo de uso : public static void main(String args[]){ Creator aCreator; aCreator = new ConcreteCreator(); Product producto = aCreator.factoryMethod(); producto.operacion(); }

Abstract Factory
Abstract Factory (Fbrica Abstracta) es un patrn de diseo para el desarrollo de software.
ndice
[ocultar]

1 Contexto y problema 2 Aspecto esttico 3 Un ejemplo 4 Vase tambin 5 Enlaces externos

Contexto y problema[editar editar cdigo]


Contexto: Debemos crear diferentes objetos, todos pertenecientes a la misma familia. Por ejemplo: las bibliotecas para crear interfaces grficas suelen utilizar este patrn y cada familia sera un sistema operativo distinto. As pues, el usuario declara un Botn, pero de forma ms interna lo que est creando es un BotnWindows o un BotnLinux, por ejemplo. El problema que intenta solucionar este patrn es el de crear diferentes familias de objetos.

El patrn Abstract Factory est aconsejado cuando se prev la inclusin de nuevas familias de productos, pero puede resultar contraproducente cuando se aaden nuevos productos o cambian los existentes, puesto que afectara a todas las familias creadas.

Aspecto esttico[editar editar cdigo]

La estructura tpica del patrn Abstract Factory es la siguiente:

Cliente: La clase que llamar a la factora adecuada ya que necesita crear uno de los objetos que provee la factora, es decir, Cliente lo que quiere es obtener una instancia de alguno de los productos (ProductoA, ProductoB).

AbstractFactory: Es la definicin de la interfaces de las factoras. Debe de proveer un mtodo para la obtencin de cada objeto que pueda crear. ("crearProductoA()" y "crearProductoB()")

Factoras Concretas: Estas son las diferentes familias de productos. Provee de la instancia concreta de la que se encarga de crear. De esta forma podemos tener una factora que cree los elementos grficos para Windows y otra que los cree para Linux, pudiendo poner fcilmente (creando una nueva) otra que los cree para MacOS, por ejemplo.

Producto abstracto: Definicin de las interfaces para la familia de productos genricos. En el diagrama son "ProductoA" y "ProductoB". En un ejemplo de interfaces grficas podran ser todos los elementos: Botn, Ventana, Cuadro de Texto, Combo... El cliente trabajar directamente sobre esta interfaz, que ser implementada por los diferentes productos concretos.

Producto concreto: Implementacin de los diferentes productos. Podra ser por ejemplo "BotnWindows" y "BotnLinux". Como ambos implementan "Botn" el cliente no sabr si est en Windows o Linux, puesto que trabajar directamente sobre la superclase o interfaz.

Un ejemplo[editar editar cdigo]


Veremos un ejemplo didctico y basado en el libro Head First Design Patterns, de O'Reilly. Supongamos que disponemos de una cadena de pizzeras. Para crear pizzas disponemos de un mtodo abstracto en la clase Pizzera que ser implementada por cada subclase de Pizzera. abstract Pizza crearPizza() Concretamente se crear una clase PizzeraZona por cada zona, por ejemplo la Pizzera de New York sera PizzeriaNewYork y la de Californa PizzeraCalifornia que implementarn el mtodo con los ingredientes de sus zonas. Las pizzas son diferentes segn las zonas. No es igual la pizza de New York que la pizza de California. Igualmente, aunque usarn los mismos ingredientes (tomate, mozzarella...) no los obtendrn del mismo lugar, cada zona los comprar donde lo tenga ms cerca. As pues podemos crear un mtodo creador de Pizza que sea Pizza(FactoriaIngredientes fi); Como vemos utilizamos la factora abstracta (no las concretas de cada zona, como podra ser IngredientesNewYork o IngredientesCalifornia). Pizza podr obtener los ingredientes de la factora independientemente de donde sea. Sera fcil crear nuevas factoras y aadirlas al sistema para crear pizzas con estos nuevos ingredientes. Efectivamente, en este ejemplo cliente es Pizza y es independiente de la Factora usada.

El creador de la Pizza ser el encargado de instanciar la factora concreta, as pues los encargados de instanciar las factoras concretas sern las pizzeras locales. En PizzeraNewYork podemos tener el mtodo crearPizza() que realice el siguiente trabajo: Pizza crearPizza() { FactoraIngredientes fi = new IngredientesNewYork(); Pizza pizza = new Pizza(fi); // Uso de la factora pizza.cortar(); pizza.empaquetar(); return pizza; } Como conclusin podemos observar que gracias a la factora de ingredientes crear una nueva zona, por ejemplo una pizzera en Barcelona, no nos implicara estar modificando el cdigo existente, solo deberemos extenderlo (uno de los pilares de la Ingeniera del software) ya crearamos la subclase de Pizzera: PizzeraBarcelona que al instanciar la factora solo debera escoger la factora de Barcelona. Obviamente se debera crear la factora de Barcelona que se encargara de crear los productos obtenidos de Barcelona. As que en ningn momento modificamos las pizzeras existentes, la superclase pizzera o las otras factoras o productos, solo creamos nuevas clases.

Abstract Factory
El patrn Abstract Factory nos permite crear, mediante una interfaz, conjuntos o familias de objetos (denominados productos) que dependen mutuamuente y todo esto sin especificar cual es el objeto concreto.

Que usos tiene el patrn Abstract Factory?


Este patrn se puede aplicar cuando:
o o o

Un sistema debe ser independiente de como sus objetos son creados. Un sistema debe ser 'configurado' con una cierta familia de productos. Se necesita reforzar la nocin de dependencia mutua entre ciertos objetos.

Estructura del Patrn Abstract Factory

El asterisco (*) representa que la clase/operacin es abstracta.

Elementos del Patrn Abstract Factory


FabricaAbstracta*: Define un conjunto de mtodos (interfaz) para la creacin de productos abstractos.
o o o

FabricaConcreta1/2: Implementa la interfaz de la FabricaAbstracta para la creacin de los distintos productos concretos. ProductoAbstractoA*/B*: Define la interfaz de los objetos de tipo ProductoA/B. ProductoConcretoA1/A2/B1/B2: Implementan su respectiva interfaz representando un producto concreto.

Pros/Contras del Patrn Abstract Factory


o o o

+ Brinda flexibilidad al aislar a las clases concretas. + Facilita cambiar las familias de productos. - Para agregar nuevos productos se deben modificar tanto las fabricas abstractas como las concretas.

Ejemplo del Patrn Abstract Factory


Teniendo en cuenta la siguiente jerarqua de clases, la cual trata de representar muy por arriba dos familias de productos (DVD y BluRay) cada uno con un par de variantes (simple y doble capa) para que permiten mostrar diferentes aspectos a tener en cuenta a la hora de usar este patrn.

Vemos como sera el producto abstracto:

1. public abstract class Disco implements Prototipo { 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. @Override public abstract String getPrecio(); public abstract String getNombre(); public abstract String getCapacidad(); @Override public abstract Prototipo clone();

12. 13. 14. 15. }

public String toString() { return getNombre() + " (" + getCapacidad() + ")"; }

El producto DVD extendemos del Disco

1. public abstract class DVD extends Disco { 2. ... 3. }

Y el producto concreto del DVD extender de la anterior clase:

1. public class DVD_CapaSimple extends DVD { 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. } } @Override public String getPrecio() { return "5.00$"; } @Override public String getNombre() { return "DVD Capa Simple"; } @Override public String getCapacidad() { return "4.7GB"; } @Override public Prototipo clone() { return new DVD_CapaSimple();

Vamos a construir un AbstractFactory que nos permita crear discos de DVD o BluRay de simple y doble capa usando el siguiente diseo:

La factora abstracta la definiramos mediante un interface:

1. public interface FabricaDiscos { 2. 3. 4. 5. } public BluRay crearBluRay(); public DVD crearDVD();

Y sobre ese interface implementamos una de las fbricas concretas, en este caso la de FabricaDiscos_CapaSimple:

1. public class FabricaDiscos_CapaSimple implements FabricaDiscos { 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. } } @Override public DVD crearDVD() { return new DVD_CapaSimple(); } @Override public BluRay crearBluRay() { return new BluRay_CapaSimple();

Veamos como quedara el cdigo fuente en Java para utilizar el patrn Abstract Factory:

1. FabricaDiscos fabrica; 2. DVD dvd;

3. BluRay bluray; 4. 5. fabrica = new FabricaDiscos_CapaSimple(); 6. dvd = fabrica.crearDVD(); 7. bluray = fabrica.crearBluRay(); 8. 9. System.out.println(dvd); 10. System.out.println(bluray); 11. 12. fabrica = new FabricaDiscos_CapaDoble(); 13. dvd = fabrica.crearDVD(); 14. bluray = fabrica.crearBluRay(); 15. 16. System.out.println(dvd); 17. System.out.println(bluray);

En el cdigo vemos que sobre la fbrica podemos crear objetos de diferentes tipos y que podramos ir creciendo en productos atendiendo a nuestras necesidades.

1. fabrica = new FabricaDiscos_CapaSimple(); 2. dvd = fabrica.crearDVD(); 3. bluray = fabrica.crearBluRay();

Espero que hayis podido apreciar la flexibilidad que nos brinda el patrn Abstract Factory.
Los patrones de diseo son soluciones que se puede aplicar a problemas recurrentes en el diseo de software, los mismos cubren aspectos como la creacin e interaccin de objetos as como la comunicacin entre ellos, ademas estos nos hacen mas fcil el reutilizar componentes de software basndose en tcnicas ya probadas una y otra vez en distintas aplicaciones pudiendo realizar diseos de una manera mas rpida y simplificada. Los patrones de diseo se dividen en tres grupos: creacionales, estructurales, y de comportamiento, en este primer post empezare hablando del patrn creacional Abstract Factory. Definicion de Abstract Factory: este patrn nos provee una interfaz para crear familias de objetos relacionados o dependientes entre ellos sin especificar una clase en concreto.

Diagrama UML

Participantes: AbstractFactory: declara una interfaz para operaciones que crean un producto abstracto ConcreteFactory : implementa la operacin para crear un producto en concreto AbstractProduct : declara una interfaz para un tipo de producot en concreto Product: define un producto que ser creado por su ConcreteFactory correspondiente e implementa la interfaz AbstractProduct Client: usa la interfaz declarada por el AbstractFactory y AbstractProduct

Entre los problemas mas comunes resueltos por el patrn Abstract Factory se encuentra: - La creacin de un objeto creando su tipo de manera dinmica de forma que no nos veamos atados a una implementacin sino a una interfaz haciendo mas fcil los cambios futuros. - Nos permite jugar con la manera de satisfacer las peticiones hacia una operacin determinada, de esta manera es mas sencillo cambiar la forma en que se atienden las peticiones desde una operacin en concreto.

- Nos permite poder manejarnos entre distintas plataformas de hardware y software al poder ser capaces de realizar diferentes manejos de las peticiones basndonos en las plataformas. Tambin es muy usado en casos donde se requiere crear una librera de clases de productos ya que solo revelamos sus interfaces mas no su implementacin .

Creando objetos con el diseo Abstract Factory.


Factory, es un patrn de diseo. En distintas paginas de la web los patrones de diseo son definidos como: soluciones simples y elegantes a problemas especficos y comunes del diseo orientado a objetos. Son soluciones basadas en la experiencia y que se ha demostrado que funcionan. Existen distintos patrones, como el command, singleton, etc, pero en este post solo hablaremos de Factory o Fbrica, especificamente con Abstract Factory o Fbrica Abstracta.

Entonces, Qu hace factory?, "este patrn delega en una clase la responsabilidad de creacin de objetos de otras clases. Puede evolucionar a un Factory Method o a un Abstract Factory".

Factory Method: "define una interfaz para crear objetos, pero deja que sean las subclases quienes decidan qu clases instanciar; permite que una clase delegue en sus subclases la creacin de objetos." Abstract Factory: " El patrn Abstract Factory proporciona una interfaz para crear familias de objetos relacionados o que dependen entre s, sin especificar sus clases concretas". "Normalmente se implementa usando Factory Method". Para entender un poco mejor el diseo Abstract Factory, he creado un pequeo ejemplo en java, para este, se me ocurri plantear lo siguiente: una empresa de Servicios de comunicacin cualquiera, puede tener varios productos que ofrecer para permitir que sus usuarios se comuniquen. Se pueden encontrar telfonos mviles, telfonos fijos, internet y tal vez otros mas. En el caso de los telfonos para poder establecer una comunicacin se necesitan los cdigos de rea para el caso de los fijos (ms el nmero telefnico), y los de la compaa para el caso de los mviles, sin embargo para el internet no necesito este tipo de cdigos, puesto que en un principio (y para este ejemplo) no realiza llamadas.

Comenc creando una interfaz llamada Servicio, donde nicamente declaro un mtodo, que para este ejemplo es llamado codigoDeServicio, pues de cada servicio ofrecido por la compaa voy a querer saber el distinto tipo de cdigo usado, para llamar.

Cree tambin otra interfaz de tipo Servicio llamada ServicioDeComunicacion, y declaro en ella un mtodo, para la creacin, que se encargaran de implementar cada fabrica.

La idea siguiente sera, crear tres clases: TelefonoMovil, TelefonoFijo e Iternet, que implementaran la interfaz Servicio, como cada clase lo requiera. Para este ejemplo, estas clases solo imprimirn el cdigo que se necesite para realizar una llamada.

Como despus voy a querer manejar varios de estos objetos, creo las clases fbricas, que implementaran la interfaz ServicioDeComunicacion:

Termino encapsulando (por decirlo de alguna manera) las tres fbricas anterios, creando una clase FabricaPrincipal que posea un metodo para crear cualquier tipo de fbrica que se pase por parametro, aseguro esto porque el tipo de dato de lo que recibe el metodo, es ServicioDeComunicacion (interfaz que implementa cada una de las fbricas)

Finalmente hago un main, para mandar a crear un objeto, para este ejemplo hice un pequeo switch, e inicialice una variable en 1, para crear un objeto TelefonoMovil, desde su fabrica.

Patrones de Diseo Software de Creacin


Introduccin
Los patrones de diseo software de creacin proporcionan ayuda a la hora de crear objetos desde el punto de vista de proporcionar un apopyo en la toma de decisiones, incluso cuando esta toma de decisiones sea de forma dinmica. Gracias a ello, ayudan a estructurar y encapsular estas decisiones. Hay ocasiones en la que nos encontraremos con que slo existe un patrn adecuado; otras en las que varios podrn ayudarnos; y otras en que se pueden combinar mltiples patrones convenientemente. Un patrn de creacin asociado a clases usa la herencia para variar la clase que se instancia, mientras que un patrn de diseo software de creacin asociado a objetos delegar la instanciacin a otro objeto. Hay dos formas de clasificar los patrones de diseo software de creacin basndose en las clases de objetos que se crean. Una es clasificar las clases que crean los objetos (Factory Method), y la otra forma est relacionada con la composicin de objetos (definir un objeto que es responsable de conocer las clases de los objetos producto). En esta caracterstica se apoyan los patrones Abstract Factory, Builder o Prototype. En muchas ocasiones los patrones de creacin compiten en su funcin. Por ejemplo, hay casos donde los patrones de creacin Protoype y Abstract Factory puede utilizarse indistintamente. En otras ocasiones Builder puede usar a los otros patrones para implementar los componentes que construye. A continuacin, definiremos algunos de los patrones de diseo software de creacin ms habituales.

Abstract Factory
Nos encontramos frente a un problema en el que debemos crear diferentes objetos, todos pertenecientes a la misma familia, como puede ser el sistema de libreras necesarias para crear interfaces grficas. Visto esto podramos decir que lo que intenta solucionar el patrn de diseo software de creacin Abstract Factory es crear diferentes familias de objetos. El patrn Abstract Factory, por tanto, se recomienda cuando se atisba la inclusin de nuevas familias de productos en un futuro, pero resultara contraproducente si que necesita aadir nuevos productos o modificar los existentes, ya que tendra repercusin en todas las familias creadas. Segn esto, podemos decir que los componentes tpicos del patrn Abstract Factory es la siguiente:

Cliente: Entidad que llamar a la fbrica adecuada que necesite para crear uno de los objetos que provee dicha factora, es decir, intentar obtener una instancia de alguno de los productos que entren en juego (ProductoA, ProductoB). AbstractFactory: Definicin de la interfaz que usarn las diferentes factoras. Como mnimo, debe ofrecer un mtodo para la obtencin de cada objeto que se pueda crear. ("crearProductoA()" y "crearProductoB()") Concrete Factories: Aqu se representarn las diferentes familias de productos. Provee la instancia concreta del objeto que se encarga de crear. Abstract Product: Definir las interfaces para la familia de productos genricos. En el diagrama son "ProductoA" y "ProductoB". El cliente trabajar directamente sobre esta interfaz, que ser implementada por los diferentes productos concretos. Concrete Product: Se encargar de la implementacin especfica de los diferentes productos.

Este sera el diagrama de clases general del patrn de creacin Abstract Factory:

Esquema del patrn Abstract Factory

En este enlace podr consultar un cdigo de ejemplo en Java del patrn de creacin Abstract Factory.

Factory Method
Este patrn de diseo software de creacin consiste en utilizar una clase constructora abstracta (similar al concepto del patrn Abstract Factory) con unos mtodos definidos y otro(s) abstracto(s): el(los) dedicado(s) a la construccin de objetos de un subtipo determinado. Como vemos, es una simplificacin del Abstract Factory, en la que la clase abstracta tiene mtodos concretos que se relacionan con los abstractos, de modo que segn usemos una u otra "hija" de esta clase abstracta, tendremos uno u otro comportamiento. El patrn de diseo software de creacin Factory Method puede ser usado cuando:

La creacin de un objeto impide su reutilizacin sin una importante duplicacin de cdigo. La creacin de un objeto requiere acceso a la informacin o recursos que no deberan estar contenidos en la clase de composicin. La administracin de la duracin de los objetos generados debe ser centralizada para garantizar un comportamiento coherente en la aplicacin.

Por tanto, los componentes del patrn de creacin Factory Method sera:

Product: define una interfaz de un objeto que metodo Factory creara. ConcreteProduct: implementa la interfaz Product para crear un producto en concreto. Creator: declara el metodo factory que devolvera un objeto del tipo product. ConcreteCreator: sobre escribe e metodo factory del creator devoler una intancia de un producto en concreto (ConcreteProduct).

Este sera el diagrama de clases general de este patrn de creacin:

Esquema del patrn Factory Method En este enlace podr consultar un cdigo de ejemplo en Java del patrn de creacin Factory Method.

Prototype
El patrn de diseo de software de creacin Prototype, sirve para crear un duplicado de un objeto, clonando, para ello, una instancia de ese objeto que ya haya sido creada. Para ello, el patrn tiene que especificar el tipo de objeto que quiere clonar, creando as un 'prototipo' de esa instancia. Este tipo o clase de objetos deber contener en su interfaz el procedimiento que permita solicitar esa copia, siendo desarrollado luego por las clases concretas del patrn que deseen crear ese clon. Como podemos ver, la principal razn de uso de este patrn de diseo software de creacin es crear las distintas clases de objetos que necesite el sistema, y hacerlo en el momento y entorno adecuados. Eso s, la lgica y diseo que necesite el sistema para la ejecucin y decisin de la creacin de estos objetos copia, se hace de forma independiente al patrn, siendo ste referido cuando el fragmento de cdigo pertinente solicite una copia del objeto que necesite. Cabe destacar que hacer una 'copia' significa crear otra instancia del objeto (siempre que este tenga la funcionalidad de clonarse) con las particularidades necesarias en ese instante.

Desacar tambin, que el API de Java dispone de interfaz Cloneable que facilita la implementacin de este patrn, hacindola compatible con otros prototipos que se encuentran en las diferentes libreras de Java. Este sera el diagrama de clases general del patrn:

Esquema del patrn Prototype Visto esto, los actores que intervienen en el patrn de creacin Prototype, son:

Cliente: actor solicitante de la creacin (clonacin) de los nuevos objetos a partir de los prototipos. Prototipo Concreto: actor (clase) que presenta unas caractersticas concretas que sern reproducidas en los nuevos objetos y que presenta la implementacin necesaria para clonarse. Prototipo: declara una interfaz, al a que accede el cliente, que sirve para la clonacin de objetos.

En este enlace podr consultar un cdigo de ejemplo en Java del patrn de creacin Prototype.

Singleton
El patrn de diseo de software de creacin Singleton (haciendo referencia a una instancia nica) busca restringir la creacin de objetos pertenecientes a una clase o el valor de un tipo a un nico objeto. Su intencin es garantizar que una clase slo sea instanciada una vez y,

adems, proporcionar un nico punto de acceso global a la misma. Esto lo consigue gracias a que es la propia clase la responsable de crear esa nica instancia, (declarando el constructor de la clase como privado) y a que se permite el acceso global a dicha instancia mediante un mtodo de clase. Para implementar el patrn singleton hay que crear un mtodo que instancie al objeto slo si todava no existe ninguna otra instancia. Para asegurar que no vuelva a ser instanciado, se limita al constructor con atributos protegidos o privados. Por esto, la implementacin del patrn puede ser complicada en programas multihilo, ya que si dos o ms hilos de ejecucin instanciaran la clase al mismo tiempo slo uno de ellos debera lograr crear el objeto. La solucin clsica para este problema es utilizar exclusin mutua en el mtodo de creacin de la clase que implementa el patrn. Ejemplos de situaciones habituales en las que convendra aplicar este ejemplo de patrn de diseo son aquellas en las que la clase principal busca controlar el acceso a un recurso nico (como puede ser el ratn o un archivo abierto en modo exclusivo) o cuando cierto tipo de datos debe estar disponible para todos los dems objetos. Este sera el diagrama de clases general del patrn de creacin Singleton:

Abstract Factory
Este patrn crea diferentes familias de objetos. Su objetivo principal es soportar mltiples estndares que vienen definidos por las diferentes jerarquas de herencia de objetos. Es similar al Factory Method, slo que esta orientado a combinar productos.

Se debe utilizar este patrn cuando:


Un sistema se debe configurar con una de entre varias familias de productos. Una familia de productos relacionados estn hechos para utilizarse juntos.

Diagrama UML

AbstractFactory: declara una interfaz para la creacin de objetos de productos abstractos. ConcreteFactory: implementa las operaciones para la creacin de objetos de productos concretos. AbstractProduct: declara una interfaz para los objetos de un tipo de productos. ConcreteProduct: define un objeto de producto que la correspondiente factora concreta se encargara de crear, a la vez que implementa la interfaz de producto abstracto. Client: utiliza solamente las interfaces declaradas en la factora y en los productos abstractos. Una nica instancia de cada FactoryConcreto es creada en tiempo de ejecucin. AbstractFactory delega la creacin de productos a sus subclases FactoryConcreto. Ahora que explique que rol ocupa cada uno en el diagrama, les pido un poco de atencin en lo siguiente: veamos que relacin tienen los FactoryConcretos con respectos a los productos. Esto es, FactoryConcreto1 crea una relacin entre un producto de la familia A y un producto de la familia B. Y, por otro lado, tenemos que el FactoryConcreto2 crea una relacin entre otros dos productos de ambas familias. Esto ya debera darnos una pista sobre el funcionamiento del AbstractFactory: se crea una clase por cada relacin que necesitemos crear. Esto quedar ms claro en el ejemplo a continuacin.

Ejemplo
Hagamos de cuenta que tenemos dos familias de objetos: 1) La clase TV, que tiene dos hijas: Plasma y LCD. 2) La clase Color, que tiene dos hijas: Amarillo y Azul (los mejores colores, sin duda! ). Ms alla de todos los atributos/mtodos que puedan tener la clase Color y TV, lo importante aqu es destacar que Color define un mtodo abstracto: public abstract void colorea(TV tv);

Este mtodo es la relacin que une las dos familias de productos.Dado que es un mtodo abstracto, Azul debe redefinirlo: public void colorea(TV tv) { System.out.println("Pintando de azul el "+ tv.getDescripcion()); } Lo mismo ocurre con Amarillo: public void colorea(TV tv) { System.out.println("Pintando de amarillo el "+ tv.getDescripcion()); } Bien, veamos las clases correspondientes antes de continuar con nuestros ejemplo.

No es necesario implementar Clonable, no se lo necesita para este patrn.

Escenario: nuestra empresa se dedica a darle un formato esttico especfico a los televisores LCD y Plasma. Se ha decidido que todos los LCD que saldrn al mercado sern azules y los plasma sern amarillos. Ahora bien, una solucin simple sera en la clase Azul colocar el LCD y en la clase Amarillo colocar el Plasma y todo funcionara de maravillas. Cual sera el problema? Que esta todo hardcodeado. Esto quiere decir que el hecho de que los LCD sean azules y los plasmas amarillos es una decisin del negocio y, como tal, puede variar (y de hecho el negocio vara constantemente). Por ejemplo, que pasa si maana Se agrega otro color o me cambian el color del LCD o mucho peor, que pasa si se crea otro producto LED y tambin se lo quiere pintar de Azul? Para evitar un dolor de cabeza conviene separar estas familias y utilizar el Abstract Factory:

Y los FactoryConcretos, que relacionan las familias:

Para ordenar un poco las cosas voy a crear un gestor de factorias:

Y, por ltimo el main:

Consecuencias

Se oculta a los clientes las clases de implementacin: los clientes manipulan los objetos a travs de las interfaces o clases abstractas. Facilita el intercambio de familias de productos: al crear una familia completa de objetos con una factora abstracta, es fcil cambiar toda la familia de una vez simplemente cambiando la factora concreta. Mejora la consistencia entre productos: el uso de la factora abstracta permite forzar a utilizar un conjunto de objetos de una misma familia. Como inconveniente podemos decir que no siempre es fcil soportar nuevos tipos de productos si se tiene que extender la interfaz de la Factora abstracta.

Ejemplo Patrn Abstract Factory

Siguiendo con la secuencia de entradas sobre patrones de diseo, en esta ocasin realizaremos un ejemplo usando el Patrn Abstract Factory.......... es uno de esos ejemplos simples pero que enmarcan el objetivo del patrn.......

Que es?

Antes que nada debemos saber que existe un patrn llamado Factory el cual permite delegar en una clase la responsabilidad de crear objetos de otras clases, basados en esto Podemos decir que el Abstract Factoryes una nueva fase de Factory, Teniendo as una

Fabrica de Objetos donde la creacin es transparente para la clase que los solicita. Debemos saber entonces que el patrn Abstract Factory nos brinda una interfaz para crear familias de Objetos relacionados sin tener que especificar sus clases concretas desde la clase cliente (Clase que los solicita)

El problema
Se solicita la creacin de diferentes vehculos de transporte (Buses, Busetas y Taxis) sin que se especifique en detalle la forma de su creacin.

La solucin.
Utilizamos el patrn Abstract Factory para independizar la forma como crearemos los objetos, de esta manera creamos familias de objetos de tipo Vehculo delegando el proceso y sin tener que entrar en detalles desde la clase solicitante.

La Aplicacin.

Una vez mas trabajamos con un ejemplo simple, veremos una aplicacin pequea que permite al usuario crear familias de vehculos de 3 tipos diferentes, Buses, Busetas y Taxis, tan solo presentamos unas opciones de seleccin donde escogeremos que Objeto crear, he internamente por medio del Patrn de Diseo ejecutamos el proceso de creacin.... Con este patrn revivimos Conceptos Bsicos de Programacin

Orientada a Objetos tales como Las Interfaces, mtodos Abstractos, Herencia, polimorfismo entre otros (si no los conocen los invito a darles una mirada aqu)...

En General la Aplicacin se divide en Clases Fabricas que permiten hacer el llamado a la creacin de Objetos, Interfaces que permiten aplicar conceptos como la Herencia y elPolimorfismo, tambin contamos con clases Concretas que representan los Objetos que crearn las Fabricas y por ultimo la clase principal que permitir delegar las solicitudes para iniciar el proceso de creacin.... Veamos!!!

Las
Interface

Interfaces.
Vehiculo.

Esta Interface es comn para todos los vehculos de nuestra fabrica, en ella se declaran 2 mtodos abstractos que sern comunes para los objetos a crear, sin importar si son Buses, Busetas o Taxis (Sabemos que por regla todos los mtodos de una interfaz son abstractos, por ello no es necesario declararlos como tal)
1 2 3 4 5
/** * interfaz donde se establece el codigo del servicio * @author chenao package interfaces;

6 7 8 9 10
}

*/ public interface Vehiculo { public void codigoDeVehiculo(); public int generarCodigo();

11

Interface

VehiculoDeTransporte.

Esta Interface ser implementada por las diferentes fabricas de de vehculos de la aplicacin, cuenta con el mtodo abstracto crearVehiculo() que ser comn para cada fabrica y como su nombre lo dice, le permitir a cada una implementar la lgica para crear sus objetos concretos.
1 2 3 4 5 6 7 8 9
} /** * interfaz que establece la creacion de un servicio * @author chenao */ public interface VehiculoDeTransporte { public Vehiculo crearVehiculo(); package interfaces;

Las

Fabricas.

Se componen por la Fabrica de Vehculos Principal que hace el llamado a las fabricas de Objetos Concretos..... estas implementan la interface VehiculoDeTransporte permitiendo crear los vehculos del tipo correspondiente y asignar el respectivo cdigo de creacin..... Clase FabricaDeVehiculos.

Esta clase sera la Fabrica Principal cuenta con un mtodo esttico que

permitir la creacin de los diferentes tipos de vehculos, aplicamos el concepto de polimorfismo para ejecutar el llamado a la Fabrica correspondiente y crear el objeto concreto solicitado por el cliente.
1 2 3
import interfaces.Vehiculo; package fabricas;

4
import interfaces.VehiculoDeTransporte;

5 6 7 8 9 10 11 12 13 14
objetoVehiculo.codigoDeVehiculo(); /** * Clase que permite la creacion de un servicio * @author chenao * */ public class FabricaDeVehiculos { public static void crearFabricaDeVehiculo(VehiculoDeTransporte factory){ /**Aplicamos Polimorfismo*/ Vehiculo objetoVehiculo= factory.crearVehiculo();

15 16 17
}

Clase FabricaBuses.
1 2
import interfaces.VehiculoDeTransporte; package fabricas; import interfaces.Vehiculo;

3 4 5 6
import clases.Bus; import javax.swing.JOptionPane;

7 8 9 10 11 12
public class FabricaBuses implements VehiculoDeTransporte{ /** * Clase que permite la creacion de un objeto Bus * @author chenao * */

13 14 15 16 17 18 19 20 21
} }

public Vehiculo crearVehiculo() { Bus miBus=new Bus(); miBus.setCodigo(miBus.generarCodigo()); JOptionPane.showMessageDialog(null, "Se ha creado un nuevo Objeto Bus return miBus; ");

Clase FabricaBusetas.
1 2 3 4
import javax.swing.JOptionPane; package fabricas; import interfaces.Vehiculo; import interfaces.VehiculoDeTransporte;

5 6 7 8 9 10
/** * Clase que permite la creacion de un objeto Buseta * @author chenao import clases.Buseta;

11 12 13 14 15

* */ public class FabricaBusetas implements VehiculoDeTransporte{ @Override public Vehiculo crearVehiculo() { Buseta miBuseta=new Buseta();

16 17 18 19 20 21 22
} }

miBuseta.setCodigo(miBuseta.generarCodigo()); JOptionPane.showMessageDialog(null, "Se ha creado un nuevo Objeto Buseta"); return miBuseta;

Clase FabricaTaxis.
package fabricas;

1 2 3 4 5 6 7 8 9 10 11 12 13

import interfaces.Vehiculo; import interfaces.VehiculoDeTransporte;

import javax.swing.JOptionPane;

import clases.Taxi;

/** * Clase que permite la creacion de un objeto Taxi * @author chenao * */ public class FabricaTaxis implements VehiculoDeTransporte{ @Override

14 15 16 17 18

public Vehiculo crearVehiculo() { Taxi miTaxi=new Taxi(); miTaxi.setCodigo(miTaxi.generarCodigo()); JOptionPane.showMessageDialog(null, "Se ha creado un nuevo Objeto Taxi"); return miTaxi; }

19 20 21 22

Las

Clases

Concretas.

Representan las clases de las que se instanciarn los objetos de tipo Vehculo (Buses, Busetas y Taxis) as como la clase principal que permite delegar las funcionalidades.....Las clases Bus, Buseta y Taxi Implementan la Interface Vehculo, y cada una permite generar un cdigo aleatorio para identificar el vehculo creado.... Clase Bus.
1 2 3 4 5 6 7 8 9 10 11
/** * clase que establece el codigo del servicio de buses import javax.swing.JOptionPane; package clases; import interfaces.Vehiculo;

* @author chenao * */ public class Bus implements Vehiculo{ private int codigo;

12 13 14 15 16
} public int generarCodigo() { int codigoBus=(int) (Math.random()*9999); return codigoBus;

17
public int getCodigo() {

18 19 20 21 22 23 24 25
} } } }

return codigo;

public void setCodigo(int codigo) { this.codigo = codigo;

public void codigoDeVehiculo() { JOptionPane.showMessageDialog(null,"El Codigo del Bus es : "+getCodigo());

26 27 28

Clase Buseta.
1 2 3
import javax.swing.JOptionPane; package clases; import interfaces.Vehiculo;

4 5
/**

6 7 8

clase que establece el codigo del servicio de busetas

* @author chenao */

9 10 11 12 13 14

public class Buseta implements Vehiculo{

private int codigo; public int generarCodigo() { int codigoBuseta=(int) (Math.random()*9999); return codigoBuseta;

15 16 17 18 19 20 21 22 23

} public int getCodigo() { return codigo; } public void setCodigo(int codigo) { this.codigo = codigo; } @Override public void codigoDeVehiculo() { JOptionPane.showMessageDialog(null,"El Codigo de la Buseta es:"+getCodigo());

24 25 26 27 28
}

Clase Taxi.
1 2 3 4 5
/** import javax.swing.JOptionPane; package clases; import interfaces.Vehiculo;

6 7 8 9 10

* clase que establece el codigo del servicio de taxis * @author chenao */ public class Taxi implements Vehiculo{ private int codigo; public int generarCodigo()

11 12 13 14 15 16 17 18 19

{ /**Generamos un codigo aleatorio para el taxi*/ int codigoTaxi=(int) (Math.random()*9999); return codigoTaxi; } public int getCodigo() { return codigo; } public void setCodigo(int codigo) { this.codigo = codigo;

20 21 22 23 24 25 26 27 28
}

} @Override public void codigoDeVehiculo() { JOptionPane.showMessageDialog(null,"El Codigo del Taxi es : "+getCodigo()); }

Clase

Principal.

Esta clase permite iniciar el sistema, en ella creamos las instancias de Fabricas y mediante un men de opciones se define y delega que Fabrica inicia el proceso de creacin...

1 2 3

package principal; import javax.swing.JOptionPane;

import fabricas.FabricaBuses;

4 5 6 7 8 9 10 11 12 13 14 15

import fabricas.FabricaBusetas; import fabricas.FabricaDeVehiculos; import fabricas.FabricaTaxis;

/** * clase principal del aplicativo donde se establecen las instancias * de las fabricas * @author chenao * */ public class Principal {

public static void main(String[] args)

16 17 18 19 20 21 22 23 24 25 26 27

{ FabricaBusetas busetas=new FabricaBusetas(); FabricaTaxis taxi=new FabricaTaxis(); FabricaBuses buses=new FabricaBuses(); String cad="",salida; cad+="Ingrese la opcin correspondiente para obtener el codigo del servicio\n"; cad+="1. Codigo servicio de Taxis\n"; cad+="2. Codigo servicio de Buses\n"; cad+="3. Codigo servicio de Busetas\n\n"; try { do { try {

28 29 30 31 32

int opcion=Integer.parseInt(JOptionPane.showInputDialog(cad)); switch (opcion) { case 1:FabricaDeVehiculos.crearFabricaDeVehiculo(taxi); break; case 2:FabricaDeVehiculos.crearFabricaDeVehiculo(buses);

33 34 35 36 37 38 39 40 41

break; case 3:FabricaDeVehiculos.crearFabricaDeVehiculo(busetas); break; default:JOptionPane.showMessageDialog(null,"No es un valor de consultavalido"); break; } } catch (Exception e) { JOptionPane.showMessageDialog(null,"No es un parametro de consulta valido"); } salida=JOptionPane.showInputDialog("Desea consultar otro codigo? S/N");

42 43 44 45 46 47 48 49 50 51 52 53
} } } while (salida.toUpperCase().equals("S")); } catch (Exception e) { JOptionPane.showMessageDialog(null,"Bye!!!"); }

Conclusiones.

Y Listo!!! Como vemos es un Patrn que al principio puede sonar un poco intimidante pero a medida que vamos trabajando con el nos damos cuenta de como podemos sacarle provecho a su aplicacin... Podemos evidenciar tambin el uso de varios conceptos de programacin orientada a objetos siendo los patrones de diseo un gran ejemplo de su aplicacin....

Programa para resolver ecuaciones lineales por los metodos de Jacobi o de Gauss-Seidel
function metodo=metodo() format long disp('QUE METODO DESEA UTILIZAR PARA RESOLVER EL PROBLEMA?'); disp('1.-MTODO DE JACOBI'); disp('2.-MTODO DE GAUSS'); disp('3.-SALIR'); n=input('SELECCIONE UNA OPCION: '); if n==1 num=input('INTODUCE EL NUMERO DE ECUACIONES: '); A=input('INTRODUCE LA MATRIZ DE COEFICIENTES: '); b=input('INTRODUCE LA MATRIZ DE COEFICIENTES INDEPENDIENTES: '); z=input('INTRODUZCA EL NUMERO DE ITERACIONES: '); X0=zeros(1,num); for f=1:z for i=1:num suma=0; for j=1:num if i~=j suma=suma+A(i,j)*X0(j); end end X(i)=(b(i)-suma)/A(i,i); fprintf('%10.4f',X(i)); end fprintf('\n'); X0=X; end elseif n==2 num=input('INTRODUCE EL NUMERO DE ECUACIONES: '); A=input('INTRODUCE LA MATRIZ DE COEFICIENTES: '); b=input('INTRIODUCE LA MATRIZ DE COEFICIENTES INDEPENDIENTES: '); z=input('INTRODUZCA EL NUMERO DE ITERACIONES: '); X0=zeros(1,num); X=X0; for f=1:z for i=1:num suma=0; for j=1:num if i~=j suma=suma+A(i,j)*X(j); end end X(i)=(b(i)-suma)/A(i,i); fprintf('%10.4f', X(i)); end X0=X;

fprintf('\n'); end elseif n==3 return; else disp('ERROR'); end

MTODO DE JACOBI y MTODO DE GAUSS-SEIDEL


Para el mtodo de Jacobi, considere un sistema Ax=b

Sea

A = D - E - F, donde D es la diagonal de A, -E la triangula inferior y -F la


sucesin que se construye = con este mtodo
superior. iterativo ser: b b b

triangular As, la Ax (D-E-F)x Dx

= (E+F)x

+
(k 1)

x =
(k)

D (E+F)x - +

-1

D- b
1

El siguiente programa resuelve mediante el mtodo de Jacobi un sistema de ecuaciones Ax=b con un error menor que una tolerancia dada tol. Note que el programa necesita un dato inicial x0. Adems, el programa se detiene si se alcanza un nmero mximo de iteraciones maxit sin que se satisfaga el criterio de convergencia.

function [x,iter]=jac(A,b,x,tol,maxit) N=diag(diag(A)); P=N-A; corr=1; errest=1; iter=0; while abs(errest)>tol & iter<maxit iter=iter+1; x0=x; corr0=corr; x=N\(P*x0+b); corr=norm(x-x0,inf); normest=corr/corr0; if normest>=1 & iter>=2 error('norma de la matriz de iteracin > 1') end

errest=normest/(1-normest)*corr;

end iter

Ejemplo:

Resuelva

Ax =b,

(0)

con

una

aproximacin

inicial

x =[0

(0)

0]'

>> A=[5 >> >> >> >> >> jac(A,b,x,tol,maxit)

-2 x=[0 b=[3

1;-1

-7 0 -2

3;2

-1

8]; 0]'; 1]'; tol=10^-6; maxit=200;

iter= 13 ans=

0.6763 0.1799 -0.0216

Para el MTODO N=tril(A) P=N-A

DE

GAUSS-SEIDEL,

modificar

P:

Codigo Jacobi Matlab


Publicado en 26 enero, 2010de dgm116

function[]=jacobi(y,v) %funcion que soluciona un sistema de ecuaciones simultaneas [r,c]=size(y);%r guarda el numero de renglones y c el numero de columnas d=diag(y);%d sera un vector el cual contendra los elementos de la %diagonal principal de la matriz formada por el sistema

%de ecuaciones h=0;%h servira de contador z=0;%z sera el valor que usaremos para condicionar k=0; for i=1:r%Inicio de despeje de incognitas for j=1:c if j~=i x(i,j)=[-y(i,j)./d(i)];%x sera una matriz la cual contendra %en sus renglones nuestras incognitas %despejadas end end end %incognitas despejadas while z~=1%ciclo que se repetira hasta encontrar el valor de las incognitas for i=1:r%este ciclo nos servira para controlar el numero de %renglon en que se este analizando y asi evaluar las %incognitas %despejadas y obtener los nuevos valores que se utilizaran %para evaluar dichas incognitas f(i)=0;%la posicion i del vector f se le asignara cero %para evitar una acomulacion for j=1:c%ciclo que nos servira para encontrar los nuevos valores %en los que se evaluara nuestras incognitas if j~=c%condicion para evitar multiplicar el valor constante f(i)=f(i)+(x(i,j).*v(j));%el vector f tomara los nuevos %valores en los se volveran a %evaluar las incognitas despejadas else f(i)=f(i)+(x(i,j)); end end end for i=1:r if f(i)==v(i)%se comparan los valores del vector f con los %del vector v h=h+1;%si se cumple la condicion el contador aumenta end end

for i=1:r v(i)=f(i);%el vector v adquiere los nuevos valores obtenidos %anteriormente end if h==r z=1;%si el contador es igual al numero de renglones quiere decir %que los valores utilizados anteriormente son iguales a los %acabados de obtener else h=0;%si no el contador regresa a cero end

S-ar putea să vă placă și