Vous êtes sur la page 1sur 45

UNIVERSIDAD MAYOR DE SAN SIMON

FACULTAD DE CIENCIAS Y TECNOLOGIA


DIRECCIÓN DE POSGRADO

“COMO APLICAR PATRONES DE DISEÑO ESTRUCTURALES

EN APLICACIONES WEB CON JAVA”

TRABAJO FINAL PRESENTADO PARA OBTENER EL CERTIFICADO DE


DIPLOMADO EXPERTO EN DESARROLLO DE APLICACIONES
EMPRESARIALES VERSIÓN I
.

POSTULANTE : Marvin Dickson Mendia Calizaya


TUTOR : Ing. Edson Ariel Terceros Torrico

Cochabamba – Bolivia
2018
Dedico este documento a mi Madre,

Hermanas y seres queridos, sin cuyo

apoyo no habría sido posible.

ii
Tabla de Contenido
TABLA DE CUADROS, GRAFICOS Y FIGURAS 4

Resumen 5

Introducción 6

1 Generalidades 7

1.1 Antecedentes Generales 7

1.2 Antecedentes Específicos 7

2 Metodología 8

3 Cómo aplicar patrones de diseño estructurales a aplicaciones web con Java 8

3.1 Aspectos a tomar en cuenta al usar el Patrón de diseño Adapter o Adaptador 8

3.2 Aspectos a tomar en cuenta al usar el Patrón de diseño Bridge o Puente 18

3.3 Aspectos a tomar en cuenta al usar el Patrón de diseño Composite o Compuesto 23

3.4 Aspectos para tomar en cuenta al usar el Patrón de diseño Decorador o Decorator 28

3.5 Aspectos a tomar en cuenta al usar el Patrón de diseño Facade o Fachada 31

3.6 Aspectos a tomar en cuenta al usar el Patrón de diseño Flyweight o Peso Ligero 37

3.7 Aspectos para tomar en cuenta al usar el Patrón Proxy 39

4 Conclusiones 43

5 Bibliografía 45
TABLA DE CUADROS, GRAFICOS Y FIGURAS

Figura 1 Estructura Patrón Adapter ................................................................................. 9

Figura 2 Estructura Clase Adapter .................................................................................. 9

Figura 3 Estructura del Patrón Bridge ........................................................................... 19

Figura 4 Estructura Patrón Composite .......................................................................... 24

Figura 5 Estructura Patrón Decorador........................................................................... 29

Figura 6 Estructura del patrón Fachada ........................................................................ 32

Figura 7 Sin y Usando el patrón Fachada ..................................................................... 33

Figura 8 Estructura patrón Flyweight............................................................................. 37

Figura 9 Estructura patrón Proxy .................................................................................. 40

4
Resumen

La ingeniería de software a sido aplicada al desarrollo de sistemas pequeños y relativamente


grandes, con baja y alta complejidad, haciendo que los sistemas se deban desarrollar de manera
más rápida y eficiente. Para ayudar a desarrollar programas robustos, mantenibles y que se
puedan modificar, se hace uso de patrones de diseño (de creación, estructurales y
comportamiento). Los patrones de diseño brindan una solución ya probada y documentada a
problemas de desarrollo de software que están sujetos a contextos similares, nos ayudan con el
ahorro de tiempo, ya que se cuentan con un conjunto de reglas y herramientas probadas por
millones de desarrolladores a lo largo de muchos años, establecen un lenguaje común que ayuda
a explicar a otras personas, ya sea que conozcan el código o no y entender de qué manera cómo
se resolvió el problema y si fue la mejor solución.

Los patrones de diseño más conocidos se dividen en distintos grupos según el tipo de problema
que resuelven:

Patrones creacionales, facilitan la tarea de creación de nuevos objetos encapsulado el proceso.


Los más conocidos son: Abstract Factory, Factory Method, Builder, Singleton, Prototype.

Patrones Estructurales, especifican la forma en la que unas clases se relacionan con otras,
separan la interfaz de la implementación. Los más conocidos son: Adaptador (Adapter), Puente
(Bridge), Compuesto (Composite), Decorador (Decorator), Fachada (Facade), Peso Ligero
(Flyweight), Proxy.

Patrones de comportamiento, gestionan algoritmos, relaciones y responsabilidades entre los


objetos. Los más conocidos son: Command, Chain of responsibility, Interpreter, Iterator,
Mediator, Memento, Observer, State, Strategy, Template Method, Visitor.

Palabras clave: Patrones de Diseño, estructurales, Adaptador (Adapter), Puente (Bridge),


Compuesto (Composite), Decorador (Decorator), Fachada (Facade), Peso Ligero (Flyweight),
Proxy

5
Introducción

Este documento propone ver el uso de patrones de diseño estructurales en aplicaciones Web
con java. Justificando el uso de estos patrones de diseño en el desarrollo de aplicaciones web.

En los últimos tiempos, las empresas e instituciones han visto que el uso del internet se ha
incrementado en estos últimos años, para mantenerse y hacerse conocer en el mercado deben
incursionar en el uso de aplicaciones web. Debido a esto existe un incremento en la necesidad
de desarrollar aplicaciones Web.

Al momento de desarrollar una aplicación, se debe contemplar los problemas de escalabilidad y


mantenimiento, con el uso de patrones de diseño estos problemas se logran solucionar. Otro
punto importante es que con los patrones de diseño se logra estandarizar la forma de programar,
ya que cada programador tiene una manera de desarrollar su código y muy probablemente otro
desarrollador haga el mantenimiento de ese código, el cual sería difícil de hacerlo si no recibe
ayuda del programador que lo desarrolló. En cambio, si se hizo uso de los patrones de diseño
para el desarrollador que va a dar mantenimiento a la aplicación web le será más fácil realizar
esa tarea.

Otro punto que se debe tomar en cuenta, es que no solo una persona trabaja en el desarrollo de
una aplicación, al hacer uso de los patrones de diseño se realizará una codificación estándar y
se tendrá una mejor comunicación entre los desarrolladores y esto significaría un menor esfuerzo
y tiempo en el desarrollo de la aplicación.

En este documento se analizará el uso de patrones de diseño estructurales en aplicaciones web


con el lenguaje de programación java. Los patrones de diseño que veremos son: Patrón
Adaptador (Adapter), Patrón Puente (Bridge), Patrón Compuesto (Composite), Patrón Decorador
(Decorator), Patrón Fachada (Facade), Patrón Peso Ligero (Flyweight) y Patrón Proxy.

Este documento contribuirá a entender un poco más estos patrones y en qué casos se puede
usar al desarrollar las aplicaciones web.

6
1 Generalidades

1.1 Antecedentes Generales

El desarrollo de software ha pasado por varias fases, las cuales le han permitido madurar poco
a poco hasta llegar a lo que se conoce ahora. Cuando el desarrollo de aplicaciones comenzó, no
se pensaba que para llevar un problema a una solución sistemática era necesario realizar un
análisis y un diseño, sino que se llegaba directamente a la implementación, sin manejar una
gestión detallada del mismo. Esto causaba en el trascurso del desarrollo una serie de
inconvenientes que no permitía que las aplicaciones fueran flexibles en cuanto a su
mantenimiento y/o adaptabilidad a diferentes ambientes. Más adelante, se vio la necesidad de
aplicar prácticas exitosas y controladas que otras ciencias usaban y era posible adaptarlas a la
ciencia computacional como los patrones de diseño entre otros. Estas técnicas de desarrollo
adoptadas han permitido a través del tiempo que el desarrollo de aplicaciones software se haga
de una manera gestionada, teniendo mayor control del mismo, que sea flexible en cuanto a
cambios que se vayan a realizar y que la mantenibilidad del mismo sea menos compleja.

En la actualidad se desarrolla software a la medida o en palabras más comunes aplicaciones


adecuadas a las necesidades de cada cliente, y el desarrollo de software genérico que son
realizados para satisfacer las necesidades de un mercado “global”. Dentro el área de software
se va observando un conjunto de aplicaciones con características comunes y pocas diferencias
en cuanto a su construcción, diseño e implementación, también se ven los productos que son
desarrollados con fines genéricos, pero a su vez pueden ser adaptados al negocio del cliente,
otorgando funcionalidades específicas para él.

1.2 Antecedentes Específicos

Los patrones de diseño son importantes en la definición y creación de una aplicación web ya que
sirven para definir la arquitectura que se va a usar y los frameworks que se adaptan a la misma.

Los patrones estructurales, se enfocan en cómo las clases y objetos se componen para formar
estructuras mayores, ellos describen cómo las estructuras compuestas por clases crecen para
crear nuevas funcionalidades, a manera de agregar a la estructura flexibilidad y que la misma

7
pueda cambiar en tiempo de ejecución, lo cual es imposible con una composición de clases
estáticas.

2 Metodología

Para el presente trabajo se utilizarán los siguientes métodos de investigación:

 Método Bibliográfico, debido a que se realizará la lectura y compilación de libros


relacionados al tema de estudio.
 Método Analítico, debido a que se procederá a revisar y analizar ordenadamente
documentos relacionados al tema de estudio, para la redacción del presente trabajo.

3 Cómo aplicar patrones de diseño estructurales a aplicaciones web con Java

A continuación, se hará una revisión de los diferentes patrones de diseño estructurales en


aplicaciones web y en qué casos se haría uso de un patrón de diseño en específico.

3.1 Aspectos a tomar en cuenta al usar el Patrón de diseño Adapter o Adaptador

Los aspectos a tomar en cuenta al usar el patrón de diseño Adapter en una aplicación web, son
hacer uso de clases existente y cuya interfaz no coincide, crear una clase reutilizable que coopere
con clases no relacionadas.

El objetivo de este patrón de diseño, es convertir la interfaz de una clase existente en la interfaz
esperada por los clientes, también existentes de modo que puedan trabajar de manera conjunta.
Según (DEBRAUWER, 2015, pág. 97)

Convierte la interfaz de una clase en otra interfaz que es la que esperan los clientes. Permite que
cooperen clases que de otra forma no podrían por tener interfaces incompatibles. Según
(GAMMA, 2002, pág. 131).

8
Figura 1 Estructura Patrón Adapter

Fuente: (GAMMA, 2002, pág. 132)

Figura 2 Estructura Clase Adapter

Fuente: (GAMMA, 2002, pág. 133)

Según la Figura 2 los compontes de este patrón son:

 Client (Cliente): Colabora con objetos que se ajustan a la interfaz Objetivo.


 Target (Objetivo): Define la interfaz específica del dominio de usa el cliente.
 Adapter (Adaptador): Adapta la interfaz de Adaptable al interfaz objetivo.
 Adaptee (Adaptable): Define una interfaz existente que necesita ser adaptable.

9
Las características que siempre están presentes en el patrón de diseño adaptador son tres:
Objetivo (Target) que es la interfaz o la clase abstracta en donde se incluyen los métodos
objetivos que son los métodos que se quieren adecuar y son métodos abstractos. Otro
componente es el Adaptador (Adapter) que es el que sirve como puente entre la clase que se va
a adaptar y el Objetivo. Y el último componente es el Adaptable (Adaptee) que es el que contiene
métodos que no son completamente compatibles con el Objetivo (Target), si yo quisiera hacer
que el Adaptable herede del Objetivo no se podría hacer ya que este contiene métodos distintos.
Entonces lo que se hace es una agregación, para así hacer uso del Adaptable y adecuarlo según
los métodos del Adaptador.

Cuando se tiene que hacer que la aplicación web que se diseñó deba cumplir nuevas
funcionalidades para ello debe crear nuevas clases, el hecho de añadir nuevas clases
evidentemente puede hacerle modificar antiguas clases, porque ocasionara, cambios en su
diagrama, a lo que esto nos lleva, es a tener que eliminar esas ideas antiguas.

Por eso, este patrón nos ayuda a reutilizar, sabiendo que las clases nuevas y clases antiguas no
se pueden conectar, porque no tienen los mismos métodos, es ahí donde entra este patrón en el
cual se crea un adaptador y gracias a este adaptador podremos llamar a las clases antiguas y
nuevas de la misma manera.

Back End

Target (Objetivo)

abstract public class Target


{
abstract public void Peticion1();
abstract public void Peticion2();

abstract public void PeticionN();


}

public class Clase1 extends Target


{

10
public Clase1(){}

@Override
public void Peticion1()
{
}

@Override
public void Peticion2()
{
}

@Override
public void PeticionN()
{
}
}

Adaptee

public class Clase2


{
public Clase2(){}

@Override
public void PeticionPropia1()
{
}

@Override
public void PeticionPropia2()
{
}

11
@Override
public void PeticionPropiaN()
{
}
}
Adapter

public class Clase2Adapter extends Target


{
private Clase2 clase2;

public Clase2Adapter(){
this.clase2 = new Clase2();
}

@Override
public void Peticion1()
{
this.clase2.PeticionPropia1();
this.clase2.PeticionPropia2();
}

@Override
public void Peticion2()
{
this.clase2.PeticionPropia3();
}

@Override
public void PeticionN()
{
this.clase2.PeticionPropiaN();

12
}
}
Cliente
public class Client
{
public static void main( String[] args )
{
Client cliente = new Client();
client.Operacion1;
client.Operacion2;
}
private void Operacion1
{
Target target = new Clase1();
target. Peticion1();
target. Peticion2();
target. PeticionN();
}
private void Operacion2
{
Target target = new Clase2Adapter();
target. Peticion1();
target. Peticion2();
target. PeticionN();
}
}
Ejemplo
Target (Objetivo)
public abstract class Animal
{
abstract public void raza();
abstract public void tamano();

13
abstract public void peso();
abstract public void color();
}

public class Perro extends Animal


{
public Perro()
{
super();
}

@Override
public void raza()
{
}

@Override
public void tamano()
{
}

@Override
public void peso()
{
}

@Override
public void color()
{
}
}

14
public class Gato extends Animal
{
public Gato()
{
super();
}

@Override
public void raza()
{
}

@Override
public void tamano()
{
}

@Override
public void peso()
{
}

@Override
public void color()
{
}
}
Adapter
public class PajaroAdapter extends Animal
{
public Pajaro pajaro;

15
public PajaroAdapter()
{
super();
this.pajaro = new Pajaro();
}

@Override
public void raza()
{
this.pajaro.alas();
this.pajaro.pico();
this.pajaro.plumaje();
}

@Override
public void tamano()
{
}

@Override
public void peso()
{
}

@Override
public void color()
{
}
}
Adaptee
public class Pajaro
{

16
public Pajaro()
{
}

public void plumaje()


{
}

public void alas()


{
}

public void pico()


{
}
}
Cliente
public class Client
{
public static void main( String[] args )
{
Client client = new Client();
client.ComprarPerro();
client.ComprarGato();
client.ComprarPajaro();
}

private void ComprarPerro()


{
Animal animal = new Perro();
animal.raza();

17
animal.tamano();
animal.peso();
animal.color();
}

private void ComprarGato()


{
Animal animal = new Gato();
animal.raza();
animal.tamano();
animal.peso();
animal.color();
}
private void ComprarPajaro()
{
Animal animal = new PajaroAdapter();
animal.raza();
animal.tamano();
animal.peso();
animal.color();
}
}

3.2 Aspectos a tomar en cuenta al usar el Patrón de diseño Bridge o Puente

Los aspectos a tomar en cuenta al usar el patrón de diseño Bridge en una aplicación web, son
evitar un enlace permanente entre una abstracción y su implementación, los cambios de una
implementación no deberían tener impacto en los clientes, permitir combinar diferentes
abstracciones y sus implementaciones, y extenderlas independientemente.

Desacopla una abstracción de su implementación, de modo que ambas puedan variar de forma
independiente. (GAMMA, 2002, pág. 141). Una abstracción se refiere a un comportamiento que
una clase debería implementar, con lo cual este patrón permite modificar las implementaciones

18
de una abstracción en tiempo de ejecución, de esta manera ambas pueden ser modificadas
independientemente sin necesidad de alterar por ella la otra.

El objetivo de este patrón es separar el aspecto de la implementación de un objeto de su aspecto


de representación y de interfaz. (DEBRAUWER, 2015, pág. 107).

Figura 3 Estructura del Patrón Bridge

Fuente: (GAMMA, 2002, pág. 143)

Según la Figura 3 los componentes de este patrón son:

 Abstraction (Abstracción): Define la interfaz de la abstracción. Mantiene la referencia a un


objeto de tipo implementador.
 RefinedAbstraction (AbstraccionRefinada): Extiende la interfaz definida por abstracción.
 Implementor (Implementador): Define la interfaz de las clases de implementación.
 ConcreteImplementor (ImplementadorConcreto): Implementa el interfaz implementador y
define su implementación concreta.

Con este patrón se puede dividir un componente complejo en 2 jerarquías independientes, pero
relacionadas, las cuales serían la abstracción funcional y la implementación interna, esto hace

19
que sea más fácil cualquier aspecto del componente. La abstracción va a tener una relación con
la implementación, la implementación tiene la capacidad de realizar el almacenamiento de la
información, mientras que, la abstracción tiene la capacidad de representar esa información de
forma independiente. De esta manera el patrón de diseño nos ayuda a minimizar la generación
de código que se realiza para independizar la funcionalidad de la representación, esto hace que
se puedan mezclar y combinar diferentes clases de representaciones y comportamientos, esto
nos da una mucho mayor funcionalidad ya que estas combinaciones producen una gama más
amplia.

Back End

Implementor (Implementador)

public interface Implementor


{
public void OperacionImp_1();
public int OperacionImp_2(int item);
public boolean OperacionImp_3();
}

ConcreteImplementor (ImplementadorConcreto)

public class ImplementorConcret_1 implements Implementor


{
@Override
public void OperacionImpl_1()
{
.
.
}

@Override
public int OperacionImp_2(int item)
{

20
.
.
return ...;
}

@Override
public boolean OperacionImpl_3()
{
return true;
}
}
public class ImplementorConcret_2 implements Implementor
{
@Override
public void Operacion_1()
{
.
.
}

@Override
public int Operacion_2(int item)
{
.
return ...;
}

@Override
public boolean Operacion_3()
{
return true;

21
}
}
Abstraction (Abstracción)

public class Abstraction{


protected bridge implementacion;

public void setImplementacion(bridge impl)


{
this.implementacion = impl;
}
public void Operacion_1()
{
implementacion.OperacionImp_1();
}
public int Operacion_2()
{
return implementacion.OperacionImp_2();
}
}

RefinedAbstraction (AbstraccionRefinada)
public class AbstraccionRefinada_1() extends Abstraction
{
@Override
public int Operacion_2(int item)
{
.
.
return ...;
}
}

22
public class AbstraccionRefinada_2() extends Abstraction
{
@Override
public void Operacion_1()
{
.
.
}
}

3.3 Aspectos a tomar en cuenta al usar el Patrón de diseño Composite o


Compuesto

Los aspectos a tomar en cuenta al usar el patrón de diseño Composite en una aplicación web,
son representar jerarquías de objetos, que los clientes sean capaces de obviar las diferencias
entre las composiciones de objetos y los objetos individuales.

Compone objetos en estructuras de árbol para representar jerarquías de parte-todo. Permite que
los clientes traten de manera uniforme a los objetos individuales a los compuestos (GAMMA,
2002, pág. 151).

Este patrón de diseño ofrece un marco de diseño de una composición de objetos de profundidad
variable, diseño que estará basado en árbol. Esta composición esta encapsulada con respecto a
los clientes de los objetos que pueden interactuar, sin tener que conocer la profundidad de la
composición. (DEBRAUWER, 2015, pág. 119).

23
Figura 4 Estructura Patrón Composite

Fuente: (GAMMA, 2002, pág. 152)

Según la Figura 4 los componentes de este Patrón son:

 Client (Cliente): Manipula objetos en la composición a través de la interfaz componente.


 Component (Componente): Declara la interfaz de los objetos de la composición.
Implementa el comportamiento predeterminado de la interfaz que es común a todas las
clases. Declara una interfaz para acceder a sus componentes hijos y gestionarlos.
 Leaf (Hoja): Representa objetos hoja en la composición. Una hoja no tiene hijos. Define
el comportamiento de los objetos primitivos de la composición.
 Composite (Compuesto): Define el comportamiento de los componentes que tienen hijos.
Almacena componentes hijos. Implementa las operaciones de la interfaz Componente
relacionada con lo hijos.

Este patrón nos permite crear una estructura compleja a partir de una estructura más simple, la
cual puede funcionar por si sola como un sistema.

Se debe identificar los tres roles que se manejan en este patrón, tales como el rol de
Componente, el rol de Compuesto y el rol de Hoja, buscando nombres apropiados y eligiendo
bien el rol que desempeña. El Componente es el que ven los clientes, este debe llevar los
atributos comunes de hoja y compuesto, luego se añade los métodos. El rol Hoja lleva los
atributos de cada hoja. El rol Compuesto lleva los atributos del compuesto respetando las
relaciones.

24
Back End

Componente
public abstract class Componente
{
private String name;

public Componente(String name)


{
this.name = name;
}

public String getName()


{
return this.name;
}

public abstract void add(Componente cc);

public abstract void remove(Componente cc);

public abstract boolean isCompuesto();

public abstract String view(String head);


}

Compuesto
public class Compuesto extends Componente
{
private java.util.List<Componente> list;

public Compuesto(String name) {


super(name);

25
this.list = new java.util.ArrayList<>();
}

@Override
public String view(String head)
{
StringBuilder result = new StringBuilder();
result.append(head + "-" + this.getName() + ":" + "\n");
for (Component item : list)
{
result.append(item.view(head + " "));
}
return result.toString();
}

@Override
public void add(Componente cc)
{
list.add(cc);
}

@Override
public void remove(Componente cc)
{
list.remove(cc);
}

@Override
public boolean isCompuesto()
{
return true;
}

26
@Override
public String toString()
{
return "C:" + this.getName().toLowerCase();
}
}

Hoja
public class Hoja extends Componente {

public Hoja(String nombre) {


super(nombre);
}

@Override
public String view(String cabecera) {
return cabecera + "-" + this.toString() + "\n";
}

@Override
public String toString() {
return "H1:" + this.getName().toLowerCase();
}

@Override
public void remove(Componente cc) {
throw new UnsupportedOperationException("Operacion no soportada");
}

@Override
public void add(Componente cc) {

27
throw new UnsupportedOperationException("Operacion no soportada");
}

@Override
public boolean isCompuesto() {
return false;
}
}

3.4 Aspectos para tomar en cuenta al usar el Patrón de diseño Decorador o


Decorator

Los aspectos a tomar en cuenta al usar el patrón de diseño Decorador en una aplicación web,
son para añadir objetos individuales de forma dinámica y transparente, es decir sin afectar a otros
objetos, cuando la extensión mediante la herencia no es viable.

Asigna responsabilidades adicionales a un objeto dinámicamente, proporcionando una


alternativa flexible a la herencia para extender la funcionalidad (GAMMA, 2002, pág. 161).

Este patrón nos permite modificar dinámicamente el comportamiento de un objeto. Puede ser
considerado como una alternativa a declarar una clase que hereda de otra. (MONTORO, 2012,
pág. 111).

28
Figura 5 Estructura Patrón Decorador

Fuente: (GAMMA, 2002, pág. 163)

Según la Figura 5 los componentes de este patrón son:

 Componente: Define la interfaz para objetos a los que se puede añadir responsabilidades
dinámicamente.
 Componente Concreto: Define un objeto al que se pueden añadir responsabilidades
adicionales.
 Decorador: Mantiene una referencia a un objeto Componente y define una interfaz que
se ajusta a la interfaz del componente.
 Decorador Concreto: Añade responsabilidades al componente.

El patrón Decorador es un patrón que envuelve un objeto con funcionalidades adicionales de


forma dinámica.

29
Back End

Componente
public abstract class Componente{
abstract public void operacion();
}
Componente Concreto
public class ComponenteConcreto extends Componente{
public void operacion(){
System.out.println("ComponenteConcreto.operacion()");
}
}

Decorador
public abstract class Decorador extends Componente{
private Componente componente;

public Decorador(Componente componente){


this.componente = componente;
}

public void operacion(){


componente.operacion();
}
}

Decorador Concreto A
public class DecoradorConcretoA extends Decorador{
private String propiedadAñadida;

public DecoradorConcretoA(Componente componente){


super(componente);

30
}

public void operacion(){


super.operacion();
this.propiedadAñadida = "Nueva propiedad";
System.out.println("DecoradorConcretoA.operacion()");
}
}

Decorador Concreto B
public class DecoradorConcretoB extends Decorador{
public DecoradorConcretoB(Componente componente){
super(componente);
}

public void operacion(){


super.operacion();
comportamientoAñadido();
System.out.println("DecoradorConcretoB.operacion()");
}
public void comportamientoAñadido(){
System.out.println("Comportamiento B añadido");
}
}

3.5 Aspectos a tomar en cuenta al usar el Patrón de diseño Facade o Fachada

Los aspectos a tomar en cuenta al usar el patrón de diseño Fachada en una aplicación web, son
proporcionar una interfaz simple para un subsistema complejo, que haya muchas dependencias
entre los clientes y las clases que implementan una abstracción, dividir en capas nuestros
subsistemas.

31
Proporciona una interfaz unificada para un conjunto de interfaces de un subsistema. Define una
interfaz de alto nivel que hace que el subsistema sea más fácil de usar (GAMMA, 2002, pág.
171).

Este patrón eleva el nivel de abstracción de un determinado sistema para ocultar ciertos detalles
de implementación y hacer más sencillo el uso (MONTORO, 2012, pág. 131)

Figura 6 Estructura del patrón Fachada

Fuente: (GAMMA, 2002, pág. 172)

32
Figura 7 Sin y Usando el patrón Fachada

Fuente: (GAMMA, 2002, pág. 172)

Según la Figura 6 los componentes de este patrón son:

 Facade (Fachada): Sabe que clases del subsistema son las responsables ante una
petición. Delega las peticiones de los clientes en los objetos apropiados del subsistema.
 Clases del subsistema: Implementan la funcionalidad del subsistema. Realizan las
labores encomendadas por el objeto Fachada. No tiene referencias a la Fachada.

Este patrón de diseño se encarga de simplificarle los procesos al cliente, haciendo que el cliente
se desentienda de toda la complejidad del sistema permitiendo realizar acciones cortas para
ejecutar procesos complejos

33
Back End

Subsistemas
public class X
{
public void m7() {
System.out.println("m7 de X");
}
}
public class Y {
public void m8() {
System.out.println("m8 de Y");
}
}
public class A {
public void m1() {
System.out.println("m1 de A");
}
public void m2() {
System.out.println("m2 de A");
}
}
public class B {
public void m3() {
System.out.println("m3 de B");
}
public void m4(A a) {
System.out.println("m4 de B");
}
}
public class C {
public void m5() {

34
System.out.println("m5 de C");
}
}
public class D {
public void m6(D d) {
System.out.println("m6 de D");
}
}

Fachada
public class SubsystemFacade {
private A a;
private B b;
private C c;
private D d;

public SubsystemFacade() {
a = new A();
b = new B();
c = new C();
d = new D();
}

public void m1_2() {


a.m1();
a.m2();
}

public void m3_4() {


b.m3();
b.m4(a);

35
}

public void m5()


c.m5();
}

public void m6() {


d.m6(d);
}
}

Cliente
public class Client
{
public void exec(){
SubsystemFacade subsystemFacade = new SubsystemFacade();
subsystemFacade.m1_2();
subsystemFacade.m3_4();
subsystemFacade.m5();
subsystemFacade.m6();
//...
X x = new X();
x.m7();
//...
Y y = new Y();
y.m8();
}
}

36
3.6 Aspectos a tomar en cuenta al usar el Patrón de diseño Flyweight o Peso
Ligero

Los aspectos a tomar en cuenta al usar el patrón de diseño Peso Ligero en una aplicación web,
son cuando una aplicación utiliza un gran número de objetos, costes de almacenamientos
elevados debido a la cantidad de objetos, muchos grupos de objetos pueden reemplazarse por
objetos compartidos y la aplicación no depende de la identidad de un objeto.

El patrón de diseño Peso Ligero usa un comportamiento para permitir un gran número de
objetos de grano fino de forma eficiente (GAMMA, 2002, pág. 179).

El patrón Peso Ligero permite compartir un objeto entre los clientes, creando una responsabilidad
para el objeto compartido que los objetos normales no necesitan considerar. Un objeto ordinario
no tiene que preocuparse mucho por la responsabilidad compartida. Muy a menudo, solo un
cliente tendrá una referencia de un objeto en cualquier momento. Cuando el cambio de estado
del objeto se debe a que el cliente lo cambió, y el objeto no tiene ninguna responsabilidad de
informar a otros clientes. A veces, sin embargo, querrá hacer arreglos para que varios clientes
compartan el acceso a un objeto (METSKER, 2006, pág. 145).

Figura 8 Estructura patrón Flyweight

Fuente: (GAMMA, 2002, pág. 182)

37
Según la Figura 8 los componentes de este patrón son:

 Flyweight (PesoLigero): Declara una interfaz a través de la cual los pesos ligeros pueden
recibir un estado extrinseco y actuar sobre él.
 ConcreteFlyweight (PesoLigeroConcreto): Implementa la interfaz PesoLigero y permite
almacenar el estado intrínseco, en caso de que lo haya. Un objeto PesoLigeroConcreto
debe poder ser compartido, por lo que cualquier estado que almacene debe ser
intrínseco, esto debe ser independiente del contexto del objeto PesoLigeroConcreto.
 UnsharedConcreteFlyweight (PesoLigeroConcretoNoCompartido): No todas las clases
de PesoLigero necesitan ser compartidas. La interfaz PesoLigero permite el
comportamiento, no fuerza a él. Los objetos PesoLigeroConcretoNoCompartido suelen
tener objetos PesoLigeroConcreto como hijos en algún nivel de la estructura de objetos
(como es el caso de filas y columnas).
 FlyweightFactory (FabricaPesosLigeros): Crea y controla objetos pesos Ligeros.
Garantiza que los pesos ligeros se compartan de manera adecuada. Cuando un cliente
solicita un peso Ligero, el objeto FabricaPesosLigeros proporciona una instancia concreta
o crea uno nuevo, en caso de que no exista ninguno.
 Client (Cliente): Mantiene una referencia de los pesos ligeros. Calcula o guarda el estado
extrínseco de los pesos ligeros.

Back End
Peso Ligero
public interface PesoLigero
{
public String Operacion();
}
Peso Ligero Concreto
public class PesoLigeroConcreto implements PesoLigero
{
public String parm;
public PesoLigeroConcreto(String parm){
this.parm = parm;

38
}
@Override
public String Operacion()
{
return "Patente: " + this.parm;
}
}

Fabrica Peso Ligero


public class FlyweightFactory
{
PesoLigero pesoLigeroConcreto;
public void listarPesoLigroConcreto(String parm[])
{
for (int i = 0; i < parm.length; i++)
{
pesoLigeroConcreto = new PesoLigeroConcreto(parm[i]);
System.out.println(pesoLigeroConcreto.Operacion());
}
}
}

3.7 Aspectos para tomar en cuenta al usar el Patrón Proxy

Los aspectos a tomar en cuenta al usar el patrón de diseño Proxy en una aplicación web, son la
necesidad de una referencia a un objeto más versátil o sofisticada que un simple puntero, cuando
queremos controlar el acceso a un componente de esta forma no tenemos que crear objetos
costosos que no serán utilizados, controlar los derechos de acceso a un objeto, gestionar
accesos múltiples de clientes a un recurso.

Proporciona un representante o sustituto de otro objeto para controlar el acceso a éste. (GAMMA,
2002, pág. 191)

39
El patrón Proxy nos da una solución para una tarea de programación muy común. Un proxy es
una clase que representa y proporciona acceso a otro objeto. Este otro objeto no siempre es un
objeto de ActionScript. Podría ser un archivo de imagen, un archivo XML, un servicio Flash
Remoting o un servicio web. (LOTT, 2007, pág. 83)

Figura 9 Estructura patrón Proxy

Fuente: (GAMMA, 2002, pág. 193)

Según la Figura 9 los componentes de este patrón son:

 Proxy: Mantiene una referencia que permite al proxy acceder al objeto real. El proxy
puede referirse a un Sujeto en caso de que las interfaces de SujetoReal y Sujeto sean la
misma. Proporciona una interfaz idéntica a la de Sujeto, de manera que un proxy pueda
ser sustituido por el SujetoReal. Controla el acceso al SujetoReal y puede ser responsable
de su creación y borrado.
 Subject (Sujeto): Define la interfaz común para el SujetoReal y el proxy, de modo que
pueda usarse un Proxy en cualquier sitio en el que se espere un SujetoReal.
 RealSubject (SujetoReal): Define un objeto real Representado.

40
El patrón de diseño proxy proporciona un objeto intermediario entre el cliente y el objeto a utilizar,
permite configurar ciertas características (como el acceso) sin necesidad de modificar la clase
original. Según la funcionalidad requerida se encuentran varios tipos de proxy, Proxy Remoto
representa un objeto de otro espacio de direcciones, Proxy Virtual retrasa la creación de objetos
costosos, Proxy de protección controla el acceso de un objeto.

Se crea un interfaz Sujeto que define toda la funcionalidad que nuestro objeto a de proveer, esta
interfaz debe ser implementada por el Sujeto Real, crearemos un objeto proxy que mantendrá
una referencia al Sujeto Real y que además implementara la interfaz Sujeto de modo que a la
hora de precisar la funcionalidad sea diferente si se está ejecutando el proxy o el Sujeto Real.

Back End

Sujeto
public interface Subject
{
public void doService();
}

Real Sujeto
public class RealSubject implements Subject
{
@Override
public void doService()
{
System.out.println("Real Subject doing service...");
}
}

Proxy
public class Proxy implements Subject
{
private Subject wrapee;

41
public Proxy(Subject wrapee)
{
this.wrapee = wrapee;
}
@Override
public void doService()
{
anotherFunctionality();
if(wrapee == null)
{
wrapee = new RealSubject(); //Just for this pattern example
}
wrapee.doService();
}
private void anotherFunctionality()
{
System.out.println("Doing another functionality from Proxy...");
}
}

public class Client


{
public static void main(String[] args)
{
Subject proxyToRealSubject = new Proxy(new RealSubject());
proxyToRealSubject.doService();
}
}

42
4 Conclusiones

El uso de patrones de diseño estructural en el desarrollo de aplicaciones Web nos ayuda a


reutilizar código, evitando generar un código innecesario, desarrollar aplicaciones robustas y
fáciles de mantener y acortando plazos de entrega.

Se mencionó que los diferentes patrones de diseño estructurales se usan según al tipo de
aplicación o necesidad que se tenga al desarrollar una aplicación Web.

Los aspectos a tomar en cuenta al momento de usar el patrón de diseño Adapter en una
aplicación web, son hacer uso de clases existente y cuya interfaz no coincide, crear una clase
reutilizable que coopere con clases no relacionadas.

Los aspectos a tomar en cuenta al usar el patrón de diseño Bridge en una aplicación web, son
evitar un enlace permanente entre una abstracción y su implementación, los cambios de una
implementación no deberían tener impacto en los clientes, permitir combinar diferentes
abstracciones y sus implementaciones, y extenderlas independientemente.

Los aspectos a tomar en cuenta al usar el patrón de diseño Composite en una aplicación web,
son representar jerarquías de objetos, que los clientes sean capaces de obviar las diferencias
entre las composiciones de objetos y los objetos individuales.

Los aspectos a tomar en cuenta al usar el patrón de diseño Decorador en una aplicación web,
son para añadir objetos individuales de forma dinámica y transparente, es decir sin afectar a otros
objetos, cuando la extensión mediante la herencia no es viable.

Los aspectos a tomar en cuenta al usar el patrón de diseño Fachada en una aplicación web, son
proporcionar una interfaz simple para un subsistema complejo, que haya muchas dependencias
entre los clientes y las clases que implementan una abstracción, dividir en capas nuestros
subsistemas.

43
Los aspectos a tomar en cuenta al usar el patrón de diseño Peso Ligero en una aplicación web,
son cuando una aplicación utiliza un gran número de objetos, costes de almacenamientos
elevados debido a la cantidad de objetos, muchos grupos de objetos pueden reemplazarse por
objetos compartidos y la aplicación no depende de la identidad de un objeto.

Los aspectos a tomar en cuenta al usar el patrón de diseño Proxy en una aplicación web, son la
necesidad de una referencia a un objeto más versátil o sofisticada que un simple puntero, cuando
queremos controlar el acceso a un componente de esta forma no tenemos que crear objetos
costosos que no serán utilizados, controlar los derechos de acceso a un objeto, gestionar
accesos múltiples de clientes a un recurso.

44
5. Bibliografía

DEBRAUWER, L. Y. (2015). Patrones de Diseño en PHP. Barcelona: Ediciones ENI.

GAMMA, E. (2002). Patrones de diseño: elementos de software orientado a objetos reutilizable.

Addison-Wesley.

GUERRERO, C. A. (s.f.). www.researchgate.net. Obtenido de

https://www.researchgate.net/publication/262439445_Patrones_de_Diseno_GOF_The_G

ang_of_Four_en_el_contexto_de_Procesos_de_Desarrollo_de_Aplicaciones_Orientadas_

a_la_Web

LEIVA, A. (s.f.). devexperto. Obtenido de https://devexperto.com/patrones-de-diseno-software/

LOTT, J. D. (2007). Advanced Actionscript 3 with Design Patterns. Peachpit Press.

METSKER, S. J. (2006). Design patterns in Java. Addison-Wesley.

MONTORO, A. F. (2012). Python 3 al descubierto.

SHVETS, A. (s.f.). Source Making. Obtenido de https://sourcemaking.com/design_patterns

VALLEJO, F. D. (s.f.). Desarrollo de videojuegos Arquitectura del motor de videojuegos.

Universidad de Castilla La Mancha.

45

Vous aimerez peut-être aussi