0% encontró este documento útil (0 votos)
2 vistas54 páginas

Centro Universitario Hidalguense: Tema

El documento aborda los patrones de diseño en programación orientada a objetos, clasificándolos en creacionales, estructurales y de comportamiento. Se detallan patrones específicos como Singleton, Factory, Abstract Factory, entre otros, explicando sus características, ventajas y desventajas. Además, incluye diagramas UML y ejemplos de código para ilustrar su implementación.

Cargado por

jocelar24jim201
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
2 vistas54 páginas

Centro Universitario Hidalguense: Tema

El documento aborda los patrones de diseño en programación orientada a objetos, clasificándolos en creacionales, estructurales y de comportamiento. Se detallan patrones específicos como Singleton, Factory, Abstract Factory, entre otros, explicando sus características, ventajas y desventajas. Además, incluye diagramas UML y ejemplos de código para ilustrar su implementación.

Cargado por

jocelar24jim201
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd

Centro Universitario Hidalguense

Tema: Patrones de Diseño

Materia: Programación Orientada a Objetos

Alumno(a): Jocelyn Lara Jiménez

Grupo: 25 A

Licenciatura: Ingeniería en Sistemas Computacionales

L.I.S.C: José Ángel Blas

Patrones de Diseño
PÁG. 1
Índice
1. Creacionales......................................................... 4
1.1 Singlenton
1.1.A Que es...................................................5
1.1.B Diagrama UML.......................................7
1.1.C Código de ejemplo................................8
1.2 Factory y Abstract factory
1.2.A Que es...................................................9
1.2.B Diagrama UML.....................................11
1.2.C Código de ejemplo..............................13
1.3 Builder
1.3.A Que es.................................................17
1.3.B Diagrama UML.....................................18
1.3.C Código de ejemplo..............................19

2. Estructurales....................................................................20
2.1 Adapter
2.1.A Que es.................................................21
2.1.B Diagrama UML.....................................22
2.1.C Código de ejemplo..............................23
2.2 Decorator
2.2.A Que es.................................................25
2.2.B Diagrama UML.....................................26
2.2.C Código de ejemplo..............................27
2.3 Proxy
2.3.A Que es.................................................28
2.3.B Diagrama UML.....................................29
2.3.C Código de ejemplo..............................30
2.4 Facade
2.4.A Que es.................................................31
2.4.B Diagrama UML.....................................32
2.4.C Código de ejemplo..............................33

3. De comportamiento.........................................................35
3.1 Observer
3.1.A Que es.................................................36
3.1.B Diagrama UML.....................................37
3.1.C Código de ejemplo..............................38
3.2 Strategy
3.2.A Que es.................................................39
3.2.B Diagrama UML.....................................40
3.2.C Código de ejemplo..............................41
3.3 State
3.3.A Que es.................................................43
PÁG. 2
3.3.B Diagrama UML.....................................44
3.3.C Código de ejemplo..............................45
3.4 Command
3.4.A Que es.................................................47
3.4.B Diagrama UML.....................................48
3.4.C Código de ejemplo..............................49

4. Referencias......................................................................54

[Link]

PÁG. 3
Los patrones de creación proporcionan diversos mecanismos de creación de objetos, que
aumentan la flexibilidad y la reutilización del código existente de una manera adecuada
a la situación.
Esto le da al programa más flexibilidad para decidir qué objetos deben crearse para un
caso de uso dado.
Ventajas:
 Creación centralizada de objetos: Los patrones de creación centralizan la lógica
para crear objetos, lo que facilita su gestión y modificación.
 Acoplamiento flexible: Estos patrones desacoplan el código que crea objetos del
código que los utiliza, lo que fomenta la flexibilidad y facilita el mantenimiento.
 Legibilidad del código: Al utilizar patrones de diseño, su código resulta más fácil de
entender y mantener, ya que estos patrones proporcionan una solución estándar a
problemas comunes.
 Escalabilidad: Los patrones pueden escalar bien con aplicaciones de gran tamaño,
especialmente cuando es necesario introducir nuevos tipos de objetos.

Desventajas
 Complejidad: La introducción de patrones a veces puede complicar demasiado el
diseño, especialmente en proyectos pequeños. No todos los problemas requieren
un patrón.
 Sobrecarga: Algunos patrones, como el Singleton, pueden introducir sobrecargas
innecesarias de memoria y recursos si no se implementan correctamente.
 Mayor número de clases: Los patrones de creación pueden dar lugar a un aumento
en el número de clases en su código, lo que puede resultar abrumador si no está
bien documentado.

Singleton
Que es

PÁG. 4
El patrón singleton, o singleton pattern en inglés, pertenece a la categoría de patrones
creativos dentro del grupo de los patrones de diseño. También se le conoce simplemente
como “singleton”. El propósito de este patrón es evitar que sea creado más de un objeto
por clase. Esto se logra creando el objeto deseado en una clase y recuperándolo como
una instancia estática. El singleton es uno de los patrones más simples, pero más
poderosos en el desarrollo de software.
Características
Si se utiliza el patrón singleton para crear una instancia de una clase, entonces el patrón
se asegura de que realmente sólo permanezca con esta instancia única. El singleton
hace que esta clase de software sea accesible globalmente. En los diferentes lenguajes
de programación, hay diferentes métodos para lograrlo. Para asegurarse de que perma-
nezca con una sola instancia única, se debe impedir que los usuarios creen nuevas insta-
ncias. Esto se logra mediante el constructor, declarando el patrón como “privado”. Esto
significa que sólo el código en el singleton puede instanciar el singleton en sí mismo. Por
lo tanto, esto garantiza que sólo un mismo objeto puede llegar al usuario.
Ventajas
Al no estar poblado de innumerables variables (globales), un singleton puede escribirse
de forma rápida y sencilla. El patrón encapsula su creación, lo que significa que también
puede ejercer un control preciso sobre cuándo y cómo se accede a él. Un patrón
singleton existente puede derivarse mediante subclases para cumplir nuevas funcionali-
dades. La funcionalidad que se utiliza se decide dinámicamente. Y, por último, pero no
menos importante, un singleton se crea exactamente cuándo se necesita, una caracterí-
stica que se denomina lazy loading. El proceso de instanciar un singleton anteriormente,
es decir antes de que se necesite, por otro lado, se llama carga ansiosa.
Desventajas
El uso desinhibido de los singletons conduce a un estado similar al de la programación
procedimental (es decir, el no orientado a objetos), y puede llevar a ensuciar el código
fuente. La disponibilidad global de patrones singleton plantea riesgos si se manejan
datos sensibles. Esto porque si se hacen cambios en el singleton, no se podrá rastrear
qué partes del programa están afectadas. Esto dificulta el mantenimiento de software,
porque los fallos de funcionamiento son difíciles de rastrear. La disponibilidad global del
patrón también dificulta la eliminación de los singleton, ya que los componentes del
software siempre pueden referirse a este singleton. En aplicaciones con muchos usuarios
(aplicaciones multiusuario), un patrón singleton puede reducir el rendimiento del
programa, porque representa un atasco de datos, al ser singular.
El patrón singleton “en la vida real”
El singleton se utiliza principalmente cuando hay que completar tareas recurrentes en la
rutina de un programa. Esto incluye los datos que tienen que
ser escritos en un archivo, por ejemplo, durante el registro, o
los trabajos de impresión que tienen que ser escritos en una
sola memoria intermedia de la impresora una y otra vez. Dado
que los controladores y los mecanismos de caché también
PÁG. 5
tienen procesos recurrentes, el patrón singleton se utiliza comúnmente para éstos
también.
Puesto que es muy difícil probar el patrón singleton, ilustraremos su funcionamiento con
el ejemplo de una pequeña empresa en la que varios empleados utilizan una sola
impresora. Un ejemplo cercano a la práctica se presenta en la Serie de Tutoriales de
Patrones de Diseño de Daniel H. Jacobsen. El patrón singleton que mostramos a conti-
nuación se basa en esto.
Cuando utilizarlo
Utiliza Singleton cuando necesite que una única instancia se comparta en todo el
sistema y no deba haber más de una instancia de la clase.

Diagrama UML

PÁG. 6
Código de ejemplo
PÁG. 7
public class Singleton {
private static Singleton instance; // protected from external access and static
private Singleton() { } // private constructor with external access protection
............public static getInstance() { // public method, call out by code
...if (instance == null) { // only if no instance exists, then create a new
instance = new Singleton();
}
return instance;
}
}

Factory y Abstract factory


PÁG. 8
Que es
El patrón Factory es uno de los patrones fundamentales a nivel de diseño orientado a
objeto. Este patrón pertenece al grupo de patrones creacionales y nos simplifica la
construcción de una jerarquía de clases y las encapsula. Sin embargo a veces a la gente
le cuesta ver como usar este patrón en su código.
¿Cuál es la finalidad del patrón Factory?
El Factory Pattern se propone resolver un problema fundamental de la instanciación (la
creación de un objeto concreto de una clase) en la programación orientada a objetos. En
principio, es posible crear un objeto directamente en la clase que requiere o en la que
debería estar, pero también es muy inflexible. Hacer esto vincula la clase al objeto en
cuestión y es imposible cambiar la instanciación al margen de la clase. Este tipo de
código se evita en el patrón Factory definiendo una operación aparte para crear el
objeto: el Método Factoría.
Ventajas del patrón de diseño Factory
En el Factory Pattern, la llamada del método de programación va totalmente separada de
la implementación de clases nuevas, algo que tiene sus ventajas. Por ejemplo, esta
condición influye particularmente en cómo puede extenderse el software. Las instancias
Factory cuentan con un alto grado de autonomía, lo cual quiere decir que te permiten
añadir clases nuevas sin que la aplicación tenga que cambiar de ninguna manera, y todo
en paralelo al tiempo de ejecución. En este proceso, basta con implementar la interfaz
Factoría e incorporar el creador como corresponda (mediante el ConcreteCreator).
Otra ventaja de este patrón es la comprobabilidad directa de los componentes Factory.
Por ejemplo, si un creador pone en marcha tres clases, su funcionalidad puede probarse
de manera individual e independiente a la clase a la que se esté apelando. En este
último caso, solo hace falta asegurarse de que apele correctamente al creador, incluso si
más adelante se extiende el software. Una ventaja adicional es la posibilidad de dar un
nombre descriptivo a los métodos Factory (a diferencia del constructor de clase).
inconvenientes
En cambio, el inconveniente principal del patrón de diseño Factory es que su implemen-
tación conlleva un aumento significativo del número de clases integradas, ya que cada
ConcreteProduct requiere un ConcreteCreator. Si bien el enfoque Factory es en principio
extremadamente provechoso de cara a la extensión del software, también resulta desve-
ntajoso si consideramos el esfuerzo que requiere. Si queremos ampliar una familia de
productos, habrá que adaptar como corresponda no solo la interfaz, también todas las
clases subordinadas del ConcreteCreator. Por este motivo, es indispensable planificar co-
rrectamente y con antelación los tipos de producto necesarios.
Abstract factory
El Abstract Factory es el primo hermano del Factory Method y muchas veces se les
confunde. Este patrón también se le conoce cómo fábrica de fábricas ya que una de sus
implementaciones se basa en que este objeto contiene otras factorías (Factory Method).

PÁG. 9
El Abstract Factory, que no el Factory Method, nos proporciona la funcionalidad de poder
crear una familia de objetos relacionados, o dependientes entre sí. Por ejemplo, dentro
de la familia de héroes nos permitiría crear los personajes, sus armas, armaduras, etc.
Abstract Factory que nos permite crear objetos de una misma familia. Dentro de la
familia de personajes podremos crear héroes, armas y en general todo lo que esté
relacionado.
Para hacer esto, la Factoría Abstracta nos proporciona una interfaz que tendremos que
implementar por cada familia que queramos crear. Si queremos crear objetos para
guerreros tendremos un Abstract Factory, si queremos crear objetos para arqueros
tendremos otra.
Por ejemplo, imagina que estás desarrollando un juego de estrategia en el que los
jugadores pueden construir diferentes tipos de edificios, como castillos, torres y
murallas. En lugar de tener una clase concreta para cada tipo de edificio, podría usar el
patrón Abstract Factory para crear una fábrica abstracta de edificios que proporcione una
interfaz para crear cada tipo de edificio. Luego, podrías crear subclases concretas de la
fábrica abstracta para cada tipo de edificio, como una fábrica de castillos, una fábrica de
torres y una fábrica de murallas.

Diagrama UML
Factory en un diagrama UML
En el software que se basa en el patrón Factory, el código de un objeto a crear (en este
contexto también conocido como producto) se externaliza a una clase aparte. Esta clase
abstracta, también llamada “creador” o, siguiendo el patrón, “factoría”, delega la instan-
ciación del objeto a una subclase (ConcreteCreator), la cual finalmente decide qué

PÁG. 10
producto se crea. Con este fin, el ConcreteCreator toma el control del método createPro-
duct() y devuelve un ConcreteProduct, que el creador puede ampliar con código de pro-
ducción antes de que pase a la interfaz como producto finalizado.

Diagrama UML

PÁG. 11
Código de ejemplo
PÁG. 12
class Car {
private $color = null;
public function __construct() {
$this->color = "white";
}
public function setColor($color) {
$this->color = $color;
}
public function getColor() {
return $this->color;
}
}
En la clase Factory, se presentan los métodos para los coches “rojos” (red) y “azules”
(blue) así como un método privado para la propia creación de clase:
class CarFactory {
private function __construct() {
}
public static function getBlueCar() {
return self::getCar("blue");
}
public static function getRedCar() {
return self::getCar("red");
}
private static function getCar($color) {
$car = new Car();
$car->setColor($color);
return $car;
}

Código de ejemplo
PÁG. 13
interface AbstractFactory {
fun createCastle(): Castle
fun createWall(): Wall
fun createTower(): Tower
}
Las subclases concretas de AbstractFactory implementan la interfaz para crear objetos
concretos:
class CastleFactory: AbstractFactory {
override fun createCastle(): Castle {
return Castle()
}

override fun createWall(): Wall {


return CastleWall()
}

override fun createTower(): Tower {


return CastleTower()
}
}

class WallFactory: AbstractFactory {


override fun createCastle(): Castle {
return Wall()
}

override fun createWall(): Wall {


return Wall()
}

override fun createTower(): Tower {


PÁG. 14
return WallTower()
}
}

class TowerFactory: AbstractFactory {


override fun createCastle(): Castle {
return Tower()
}

° override fun createWall(): Wall {


return TowerWall()
}

override fun createTower(): Tower {


return Tower()
}
}
Las clases concretas representan cada tipo de objeto de la familia:
class Castle {
// ...
}

class CastleWall: Wall {


// ...
}

class CastleTower: Tower {


// ...
}

class Wall {
PÁG. 15
// ...
}

class WallTower: Tower {


// ...
}

class Tower {
// ...
}

PÁG. 16
Builder
Que es
Es un tipo de plantilla de patrón de diseño que sirve para resolver tareas de programa-
ción en una programación orientada a objetos. Los patrones Builder (o Constructor)
facilitan a los desarrolladores el proceso de programación porque no han de rediseñar
cada paso que se repite como una rutina de programa.
En vez de rediseñar cada paso, pueden utilizar una solución establecida. Los elementos
de software se basan en el libro Design Pattern: Elements of Reusable Object-Oriented
Software publicado en 1994 por cuatro desarrolladores de software estadounidenses
conocidos como la Gang of Four, o GoF para abreviar.
Ventajas del patrón de diseño Builder
La construcción y la representación (salida) se incorporan por separado. Las representa-
ciones internas del constructor están ocultas para el director. Las nuevas representacio-
nes como tal pueden integrarse fácilmente utilizando clases de constructores concretos.
El proceso de construcción lo controla explícitamente el director. Si hay que hacer
cambios, pueden hacerse sin consultar al cliente.
Inconvenientes de Builder
El patrón Constructor consta de un fuerte vínculo entre el producto, el constructor espe-
cífico y las clases del proceso de diseño, así que puede ser difícil hacer cambios en el
proceso básico. La construcción de los objetos requiere conocer su uso y su entorno
concretos. Utilizar patrones conocidos, como el patrón de diseño Builder, puede hacer
que los programadores pasen por alto soluciones más sencillas y elegantes. En el fondo,
muchos desarrolladores consideran que este es uno de los patrones de diseño menos im-
portantes.

Diagrama UML

PÁG. 17
Código de ejemplo
PÁG. 18
class Pizza {
var size: String? = null
var crust: String? = null
var ingredients: List<String>? = null
var price: Double? = null

class Builder {
private val pizza = Pizza()

fun size(size: String) = apply { [Link] = size }


fun crust(crust: String) = apply { [Link] = crust }
fun ingredients(vararg ingredients: String) = apply { [Link] =
[Link]() }
fun price(price: Double) = apply { [Link] = price }

fun build() = pizza


}
}
val pizza = [Link]()
.size("medium")
.crust("thick")
.ingredients("cheese", "pepperoni", "mushrooms")
.price(12.50)
.build()

2. Estructurales
PÁG. 19
Los patrones de diseño estructural se centran en organizar clases y objetos para
construir estructuras de software más grandes, eficientes y fáciles de mantener.
Simplifican las relaciones, fomentan la reutilización de código y ayudan a crear
arquitecturas escalables.
Este patrón resulta especialmente útil para lograr que las bibliotecas de clases
desarrolladas de forma independiente funcionen conjuntamente.
Los patrones de diseño estructural describen formas de componer objetos para lograr
nuevas funcionalidades.
La mayor flexibilidad de la composición de objetos proviene de la capacidad de cambiar
la composición en tiempo de ejecución, lo cual es imposible con la composición de clases
estática.
Ejemplo: Un editor de dibujo que permite a los usuarios dibujar y organizar elementos
gráficos (líneas, polígonos, texto, etc.) en imágenes y diagramas. La abstracción clave
del editor de dibujo es el objeto gráfico, que tiene una forma editable y puede dibujarse
a sí mismo.

Adapter
PÁG. 20
Que es
El Adapter es un patrón de diseño estructural que permite que clases con interfaces
incompatibles trabajen juntas al convertir la interfaz de una clase en otra que el cliente
espera. Es útil para conectar sistemas antiguos con nuevos sin modificar su código.
Ejemplo del mundo real
Mediante la implementación del patrón de diseño Adapter crearemos un adaptador que
nos permite interactuar de forma homogénea entre dos API bancarías, las cuales nos
permite aprobar créditos personales, sin embargo, las dos API proporcionadas por los
bancos cuenta con interfaces diferentes y aunque su funcionamiento es prácticamente
igual, las interfaces expuestas son diferentes, lo que implica tener dos implementaciones
diferentes para procesar los préstamos con cada banco. Mediante este patrón crearemos
un adaptador que permitirá ocultar la complejidad de cada implementación del API,
exponiendo una única interface compatible con las dos API proporcionadas, además que
dejáramos el camino preparado por si el día de mañana llegara una nueva API bancaría.
Ventajas del patrón de diseño Adapter:
 Promueve la reutilización del código sin modificaciones.
 Permite que las clases se centren en la lógica principal al aislar la adaptación.
 Admite múltiples interfaces mediante adaptadores intercambiables.
 Desacopla el sistema de las implementaciones, facilitando las modificaciones y los
intercambios.
Desventajas del patrón de diseño Adapter:
 Añade complejidad y puede dificultar la comprensión del código.
 Introduce una ligera sobrecarga de rendimiento debido a la indirección adicional.
 El uso de múltiples adaptadores aumenta el esfuerzo de mantenimiento.
 Gestionar múltiples interfaces puede requerir varios adaptadores, lo que complica
el diseño.
Los componentes del patrón de diseño del adaptador:
 Interfaz de destino : La interfaz que espera el cliente, que define las operaciones
que puede utilizar.
 Adaptee : La clase existente con una interfaz incompatible que necesita
integración.
Diagrama UML

PÁG. 21
Código de ejemplo
class OldSystem {
constructor() {
[Link] = function() {
PÁG. 22
return "Datos del sistema antiguo";
};
}
}

class NewSystem {
constructor() {
[Link] = function() {
return "Datos del sistema nuevo";
};
}
}

// Adaptador
class Adapter {
constructor(oldSystem) {
[Link] = oldSystem;
}

fetchData() {
return [Link]();
}
}

// Uso del Patrón Adapter


const oldSystem = new OldSystem();
const adapter = new Adapter(oldSystem);

[Link]("Sistema antiguo a través del adaptador:", [Link]());

const newSystem = new NewSystem();


PÁG. 23
[Link]("Sistema nuevo:", [Link]());

Decorator Que es
Este patrón permite agregar funcionalidades adicionales a un objeto de forma dinámica,
sin necesidad de crear subclases para cada combinación de funcionalidades.

PÁG. 24
El patrón Decorator se implementa mediante la creación de una interfaz que define la
funcionalidad base del objeto a decorar, y una clase base que implementa esta interfaz y
que servirá como punto de partida para crear las decoraciones.
Las decoraciones son clases que implementan la misma interfaz que el objeto base, y
que contienen una referencia a un objeto de la clase base.
Por ejemplo,imagina que queremos crear una aplicación que permita a los usuarios
comprar pizzas con diferentes ingredientes.
Para ello, podemos crear una interfaz Pizza que define la funcionalidad básica de una
pizza, como su tamaño y su precio, y una clase base PizzaBase que implementa esta
interfaz y que representa una pizza básica sin ingredientes adicionales.
El patrón Decorator nos permite agregar funcionalidades adicionales a un objeto de
forma dinámica y sin necesidad de crear subclases para cada combinación posible esto
nos permite mantener un código limpio y fácil de extender en el futuro.
En resumen, el patrón Decorator es una herramienta muy útil en la programación
orientada a objetos, y podemos implementarlo de forma sencilla utilizando interfaces y
clases.
Considerar el patrón de diseño Decorator al diseñar un programa es útil por varias
razones. En primer lugar, utilizar la estructura Decorador conlleva un alto grado de flexi-
bilidad: las funcionalidades de las clases pueden ampliarse durante la compilación y
durante el tiempo de ejecución sin necesidad de recurrir a una jerarquía de clases
basadas en la herencia. Esto mejora significativamente la legibilidad del código del
programa.
Debido a que la funcionalidad se divide en varias clases decoradoras, el rendimien-
to del software puede incrementarse. Esto facilita la recuperación e iniciación de
funciones específicas. Con una clase base compleja que proporciona permanentemente
todas las funciones, esta opción de recursos optimizados no está disponible.
Sin embargo, desarrollar usando el patrón Decorador tiene también algunas desventajas.
Con la introducción del patrón aumenta la complejidad del software de forma automáti-
ca. La interfaz Decorador, en particular, suele contener mucho texto y términos nuevos,
lo que aumenta su complejidad. Otra desventaja es el gran número de objetos
Decorador, razón por la cual se recomienda una sistematización separada para
evitar problemas de visualización al trabajar con subclases.
Diagrama UML

PÁG. 25
Código de ejemplo
PÁG. 26
public class EmpleadoDecorator implements Person {
private Empleado empleado;
public EmpleadoDecorator(Empleado empleado){
[Link] = empleado;
}
public String getName(){
// llama al método de la clase empleado
String name = [Link]();
// Asegúrate de que la primera letra está en mayúsculas
name = [Link]([Link](0))
+ [Link](1, [Link]());
return name;
}
}

Proxy que es
PÁG. 27
El patrón de diseño Proxy es un patrón de diseño estructural que proporciona un
intermediario para acceder a un objeto real. El objeto proxy controla el acceso al objeto
real, añadiendo una capa adicional de funcionalidad, como registro de eventos,
almacenamiento en caché o control de acceso.
Esta guía explica el patrón de diseño Proxy de forma sencilla, con una analogía del
mundo real, una explicación paso a paso de su implementación en Java y explicaciones
detalladas.
Analogía del mundo real: Un guardia de seguridad
Imagínese una instalación de alta seguridad:
🔸 Objeto real: La instalación (por ejemplo, una sala de servidores).
🔸 Proxy: Un guardia de seguridad apostado en la entrada.
🔸 Cliente: Persona que intenta entrar en las instalaciones.
El guardia de seguridad (representante) verifica la identificación del visitante y solo le
permite el acceso si cuenta con la autorización correspondiente. Si se le niega el acceso,
el visitante no llega a las instalaciones.
De manera similar, en el patrón de diseño Proxy:
🔸El objeto real (instalación) es el recurso que se protege o al que se accede.
🔸El proxy (guardia de seguridad) es el intermediario que controla el acceso.
Ventajas
1. Control de acceso: Restringe el acceso a recursos específicos.
2. Inicialización diferida: Retrasa la creación del objeto real hasta que sea realmente
necesario.
3. Funcionalidad adicional: Añade características como el registro de eventos, el
almacenamiento en caché o la validación de solicitudes sin modificar el objeto real.
Desventajas
1. Mayor complejidad: Añade una capa adicional, lo que podría complicar el diseño.
2. Sobrecarga: Introduce procesamiento adicional, lo que puede afectar al
rendimiento.

Diagrama UML
┌─────────────────────┐
│ <<interface>> │

PÁG. 28
│ Sujeto │
├─────────────────────┤
│ + operacion(): void │
└──────────┬──────────┘
│ implements
┌────────┴────────┐
│ │
┌────────┴────────┐ ┌─────┴───────────┐
│ SujetoReal │ │ Proxy │
├─────────────────┤ ├─────────────────┤
│ + operacion() │ │ - sujetoReal: Sujeto│
│ // lógica real│ │ + operacion(): void │
└─────────────────┘ └────────────────────┘
│ usa ──▶ SujetoReal

PÁG. 29
Código de ejemplo
// Sin proxy: todas las imágenes se cargan al crear el documento
public class Editor {
private List<ImagenReal> imagenes = new ArrayList<>();

public void abrirDocumento(String ruta) {


// Carga TODAS las imágenes de disco inmediatamente
for (String archivo : obtenerRutasImagenes(ruta)) {
[Link](new ImagenReal(archivo)); // Lectura costosa
}
}
}

PÁG. 30
Facade que es
¿Qué es el facade pattern?
El patrón fachada es uno de los 23 design patterns de los GoF, que fueron publicados en
1994 por los autores Erich Gamma, Ralph Johnson, Richard Helm y John Vlissides en
“Patrones de diseño: elementos de software orientado a objetos reutilizable” como guía
para los desarrolladores de software. En general, estos patrones tienen como objetivo si-
mplificar la creación de software flexibles y reutilizables. El patrón fachada define una
solución modelo para una fusión simple de diferentes interfaces en sistemas complejos.
Una clase de fachada universal, que también funciona como interfaz, delega importantes
funcionalidades del software a los respectivos subsistemas para que el manejo de los
diversos subcomponentes de un programa sea lo más sencillo posible.
¿Qué problemas soluciona el patrón fachada?
Los clientes que acceden a un subsistema complejo se refieren directamente a un gran
número de objetos con interfaces completamente diferentes o dependen de estos
objetos. Esto hace que la implementación, adaptación, prueba y reutilización de los
clientes sea particularmente difícil para los desarrolladores. Aquí es donde el facade
pattern puede ser útil.
El patrón fachada define un objeto de fachada central que:
 implementa una interfaz universal para las distintas interfaces del subsistema o
subsistemas.
 y (si es necesario) puede realizar funciones adicionales antes o después de
reenviar una solicitud al cliente.
Como intermediario, el objeto de fachada garantiza que el acceso y la comunicación con
los componentes individuales de un subsistema se simplifiquen y se reduzca al
mínimo la dependencia directa de estos componentes. Este delega las llamadas de los
clientes para que éstos no necesiten conocer las clases o sus relaciones y dependencias.

Ventajas Desventajas

Minimiza la complejidad de los sub- Aplicación compleja (especialmente en un


sistemas código existente)

Promueve el principio de acoplamie- La aproximación está acompañada por un


nto suelto nivel adicional de indirección

El software se vuelve más flexible y Alto grado de dependencia en la interfaz


fácilmente expandible de la fachada

Diagrama DML

PÁG. 31
Código de ejemplo

PÁG. 32
En primer lugar, creamos la interfaz [Link] usando el siguiente código:
public interface Shape {
void draw();
}
En segundo lugar, se crean tres clases concretas que implementan la
interfaz: [Link] (clase para objetos rectangulares), [Link] (clase para
objetos cuadrados) y [Link] (clase para objetos redondos).
public class Rectangle implements Shape {
@Override
public void draw() {
[Link]("Rectangle::draw()");
}
}
public class Square implements Shape {
@Override
public void draw() {
[Link]("Rectangle::draw()");
}
}
public class Circle implements Shape {
@Override
public void draw() {
[Link]("Rectangle::draw()");
}
}
Por último, la clase de fachada ShapeMaker se integra en el código que será llamado por
los clientes para crear las diferentes formas:
public class ShapeMaker {
private Shape circle;
private Shape rectangle;
private Shape square;
public ShapeMaker() {
PÁG. 33
circle = new Circle();
rectangle = new Rectangle();
square = new Square();
}
public void drawCircle(){
[Link]();
}
public void drawRectangle(){
[Link]();
}
public void drawSquare(){
[Link]();
}
}

3. De comportamiento

PÁG. 34
El comportamiento se refiere a cómo actúa una persona; es decir, consiste en las tareas
que realiza para interactuar en un entorno. En el desarrollo de software orientado a
objetos, el comportamiento de los diferentes objetos determina la relación entre ellos y
también su capacidad para realizar una tarea específica.
La capacidad de una aplicación de software orientada a objetos para realizar una tarea
depende de la interacción de diversos objetos y clases. Para crear software orientado a
objetos eficiente, debemos seguir ciertas pautas que describen cómo los diferentes
objetos y clases se comunican entre sí para lograr resultados. Aquí es donde entran en
juego los Patrones de Diseño de Comportamiento (BDSP). Se trata de una colección de
plantillas que se centran en el diseño de la interacción entre objetos y clases.
Los patrones de comportamiento se basan en el principio de que los objetos en una
aplicación orientada a objetos deben estar interconectados de tal manera que se evite la
codificación rígida y se gestione adecuadamente la entrada del usuario. Para ello, los
patrones de diseño de comportamiento utilizan técnicas de acoplamiento flexible para
garantizar un flujo de información ágil y eficaz.
Los sistemas de software orientados a objetos con acoplamiento débil son aquellos en
los que los componentes (clases y objetos) están débilmente asociados entre sí. Debido
a esta débil asociación, las interacciones entre objetos en sistemas con acoplamiento
débil no son tan efectivas como en sistemas con acoplamiento fuerte. Sin embargo, los
objetos en un sistema con acoplamiento débil son más independientes y reutilizables, ya
que cualquier cambio realizado en un componente tiene un efecto mínimo en la
existencia o el rendimiento de otro componente.
¿Qué problemas resuelven los patrones de diseño de comportamiento?
 Reduce la complejidad de la comunicación entre los objetos.
 Proporciona los mejores principios de interacción de objetos para el desarrollo de
software.
 Reduce el acoplamiento entre los emisores y los receptores y permite una mayor
flexibilidad de comunicación en la aplicación.
 Se utiliza para ahorrar recursos que utiliza una aplicación, ya que una mejor
interacción entre objetos conlleva una mejor ejecución de las tareas.

Observer que es
El patrón de diseño Observer, Observer Pattern o patrón observador es uno de los
patrones de diseño de software más populares. Esta herramienta ofrece la posibilidad
de definir una dependencia uno a uno entre dos o más objetos para transmitir todos
los cambios de un objeto concreto de la forma más sencilla y rápida posible. Para conse-
PÁG. 35
guirlo, puede registrarse en un objeto (observado) cualquier otro objeto, que funcionará
como observador. El primer objeto, también llamado sujeto, informa a los observadores
registrados cada vez que es modificado.
Como ya hemos mencionado, el patrón Observer es uno de los patrones GoF incluidos en
el libro de 1994 Design Patterns: Elements of Reusable Object-Oriented Software. Las
más de 20 soluciones de diseño descritas en esta publicación siguen teniendo un papel
importante hoy en día en la conceptualización y el desarrollo de aplicaciones informáti-
cas.
El patrón Observer trabaja con dos tipos de actores: por un lado, el sujeto, es decir, el
objeto cuyo estado quiere vigilarse a largo plazo. Por otro lado, están los objetos obser-
vadores, que han de ser informados de cualquier cambio en el sujeto.
Sin el patrón Observer, los objetos observadores tendrían que solicitar al sujeto regular-
mente que les enviase actualizaciones acerca de su estado (status updates). Cada una
de estas solicitudes conllevaría tiempo de computación y requeriría, además, ciertos
recursos de hardware. El patrón Observer se basa en la idea de centralizar la tarea de
informar en manos del sujeto. Para conseguirlo, existe una lista en la que los observado-
res pueden registrarse. En caso de modificación, el sujeto los informa uno tras otro, sin
necesidad de que los observadores lo pidan activamente. Si, más adelante, un observa-
dor ya no necesita las actualizaciones automáticas, puede simplemente retirarse de la
lista.

Diagrama UML
El modo de funcionamiento y uso de los patrones de diseño, como el patrón Observer, suele ser
difícil de entender para quienes no están familiarizados con el tema. Para facilitar la compren-
sión, puede ser útil observar una representación gráfica del patrón de diseño. El extendido
lenguaje de modelamiento UML (Unified Modeling Language) se adecúa especialmente a este
propósito, ya que permite describir las relaciones de forma comprensible e intuitiva, tanto para
los usuarios de la aplicación, como para los expertos. Por eso, hemos escogido UML como
lenguaje de modelación para ofrecer la siguiente representación abstracta del patrón Observer.
PÁG. 36
Código de ejemplo
class emisor extends Observable {
public emisor(){
[Link](new receptores_1());
[Link](new receptores_2());
tell("Text");
PÁG. 37
}
public void tell(String info){
if(countObservers()>0){
setChanged();
notifyObservers(info);
}
}
}
class receptores extends JFrame implements Observer{
private JTextField field;
public receptores (){
field1 = new JTextField("a");
add(field);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(300, 50);
setVisible(true);
}
public void update(Observable o, Object arg) {
[Link]((String) arg);
}
}

PÁG. 38
Strategy que es
¿En qué consiste el strategy pattern?
El strategy pattern pertenece a los llamados behavioural patterns o patrones de compor-
tamiento, que equipan un software con diferentes métodos de resolución. Estas estrate-
gias consisten en una familia de algoritmos que están separados del programa real y son
autónomos, es decir intercambiables. Un strategy pattern también incluye algunas
pautas y ayudas para los desarrolladores. Por ejemplo, los strategy patterns describen
cómo construir u organizar un grupo de clases y crear objetos. Una característica
especial del patrón strategy es que un comportamiento variable de programas y
objetos también se puede realizar en el tiempo de ejecución de un software.
¿Cuáles son las ventajas y e inconvenientes del strategy pattern?
Las ventajas de usar un strategy pattern son más evidentes desde la perspectiva de un
programador y administrador de sistemas. El desglose en módulos y clases autónomas
ayuda a estructurar mejor el código del programa. Puesto que los módulos estén delimi-
tados en nuestra aplicación de ejemplo, la tarea del programador será más sencilla. Así
pues, se puede limitar el alcance de la clase Navigator mediante la externalización de las
estrategias y se puede prescindir de la creación de subclases en Context.
Las dependencias internas de los segmentos se mantienen dentro de los límites de un
código más reducido y claramente definido. Por ello, los cambios tienen menos efecto, es
decir, no suelen conllevar más cambios (que requieren mucho tiempo) en la programa-
ción. En algunos casos, los cambios derivados incluso pueden descartarse por completo.
Los segmentos de código más claros también pueden mantenerse mejor a largo plazo y
el diagnóstico y la resolución de problemas se facilitan.
El manejo se hace más sencillo, ya que la aplicación de ejemplo se puede equipar con
una interfaz fácil de usar. Los usuarios pueden usar los botones para controlar el compor-
tamiento del programa (cálculo de la ruta) de forma variable y elegir entre las opciones
de forma sencilla.
Los strategy patterns simplifican la difícil programación del software orientado a objetos
gracias a otra de sus virtudes: permiten el diseño de software reutilizable (módulos) que
se puede implementar repetidamente y cuyo desarrollo se considera particularmente
difícil. Esto significa que las clases Context relacionadas también podrían utilizar las es-
trategias externalizadas para calcular las rutas a través de la interfaz y ya no tendrían
que aplicarlas por sí mismas.
Debido a su estructura más compleja, el diseño del software puede crear redundancias e
ineficiencias en la comunicación interna. Por ejemplo, la interfaz strategy genérica, que
todos los algoritmos deben aplicar por igual, a veces puede acabar sobredimensionada.

Diagrama UML
Los strategy patterns se diseñan generalmente con el lenguaje de modelado gráfico UML
(Unified Modeling Language). Sirven para visualizar los patrones de diseño con una notación es-
tandarizada y utilizan caracteres y símbolos especiales. El UML establece distintos tipos de
PÁG. 39
diagramas para la programación orientada a objetos. Para representar un strategy pattern, se
suelen utilizar los llamados diagramas de clase con al menos tres componentes básicos:

 Context (contexto o clase de contexto)


 Strategy (estrategia o clase de estrategia)
 ConcreteStrategy (estrategia concreta)

Código de ejemplo
public class Context {
// Valor por defecto (comportamiento por defecto): ConcreteStrategyA
private Strategy strategy = new ConcreteStrategyA();
PÁG. 40
public void execute() {
//delega el comportamiento a un objeto de estrategia
[Link]();
}
public void setStrategy(Strategy strategy) {
strategy = strategy;
}
public Strategy getStrategy() {
return strategy;
}
}
nterface Strategy {
public void executeAlgorithm();
}
class ConcreteStrategyA implements Strategy {
public void executeAlgorithm() {
[Link]("Concrete Strategy A");
}
}
class ConcreteStrategyB implements Strategy {
public void executeAlgorithm() {
[Link]("Concrete Strategy B");
}
}
public class Client {
public static void main(String[] args) {
//Comportamiento por defecto
Context context = new Context();
[Link]();
//Cambiar el comportamiento
[Link](new ConcreteStrategyB());
PÁG. 41
[Link]();
}
}

State que es
El patrón de diseño State es un patrón de comportamiento que nos permite cambiar el
comportamiento de un objeto en función del estado en el que se encuentre.

PÁG. 42
Este patrón nos permite desacoplar el comportamiento de un objeto de su
implementación, lo que nos permite cambiar el comportamiento de un objeto en tiempo
de ejecución de forma sencilla y mantenible.
El patrón de diseño State nos permite cambiar el comportamiento de un objeto en
función de su estado.
Podemos implementar este patrón mediante el uso de una interfaz que represente los
estados del objeto y una clase que represente la máquina de estados finitos del objeto.
Cada una de las clases que representan los estados del objeto implementan el método
correspondiente al comportamiento que se desea en cada estado, lo que nos permite
cambiar el comportamiento del objeto en tiempo de ejecución de forma sencilla y
mantenible.

PÁG. 43
Diagrama UML

PÁG. 44
Código de ejemplo
class State {
handle(context) {}
}

class StateA extends State {


handle(context) {
[Link]("Estado A: Cambiando al Estado B");
[Link](new StateB());
}
}

class StateB extends State {


handle(context) {
[Link]("Estado B: Cambiando al Estado A");
[Link](new StateA());
}
}

class Context {
constructor() {
[Link] = new StateA(); // Estado inicial
}

setState(state) {
[Link] = state;
}

request() {
[Link](this);
}
PÁG. 45
}

// Uso del Patrón State


const context = new Context();

[Link](); // Estado A: Cambiando al Estado B


[Link](); // Estado B: Cambiando al Estado A
[Link](); // Estado A: Cambiando al Estado B

PÁG. 46
Command que es
El patrón comando es un patrón de diseño de comportamiento que convierte una
solicitud en un objeto independiente que contiene toda la información sobre la solicitud.
Esta transformación te permite pasar solicitudes como argumentos de método, retrasar
o poner en cola la ejecución de una solicitud y admitir operaciones que se pueden
deshacer.
¿Qué problema resuelve el patrón comando?
El patrón comando resuelve, por ejemplo, el problema de múltiples botones en tu
aplicación editor de texto. Gracias a este patrón puedes tener los botones sin la
necesidad de múltiples subclases de controladores de clic y código repetido.
El patrón Comando sugiere que los objetos no deben enviar solicitudes directamente,
sino extraer todos los detalles de una solicitud, el objeto al que se llama, el nombre del
método y la lista de argumentos en una clase de comando separada con un solo método
que activa esta solicitud.
Deberías usar patrón Comando cuando quieras parametrizar objetos con operaciones.
Este patrón puede convertir una llamada de método específico en un objeto
independiente. De esta manera puedes pasar comandos como argumentos de método,
almacenarlos dentro de otros objetos, o cambiar comandos vinculados en tiempo de
ejecución.
Pros y contras del patrón comando
Los siguientes son algunos de los “pros y conntras” de este patrón.

Pros Contras

Principio de responsabilidad única.  El código puede volverse más


Puedes desacoplar las clases que complicado ya que estás
invocan operaciones de las clases introduciendo una capa
que realizan estas operaciones. completamente nueva entre
remitentes y receptores.
Principio abierto/cerrado. Puedes
introducir nuevos comandos en la
aplicación sin romper el código de
cliente existente.
Puedes implementar
deshacer/rehacer
Puedes implementar la ejecución
diferida de operaciones

Diagrama DML

PÁG. 47
Código de ejemplo
abstract class Command is

PÁG. 48
protected field app: Application
protected field editor: Editor
protected field backup: text

constructor Command(app: Application, editor: Editor) is


[Link] = app
[Link] = editor

// Realiza una copia de seguridad del estado del editor.


method saveBackup() is
backup = [Link]

// Restaura el estado del editor.


method undo() is
[Link] = backup

// El método de ejecución se declara abstracto para forzar a todos los comandos


concretos a proporcionar sus propias implementaciones. El método debe devolver
verdadero o falso dependiendo de si el comando cambia el estado del editor.
abstract method execute()

// Los comandos concretos van aquí.


class CopyCommand extends Command is
// El comando copiar no se guarda en el historial ya que no cambia el estado del
editor.
method execute() is
[Link] = [Link]()
return false

class CutCommand extends Command is


// El comando cortar no cambia el estado del editor, por lo que debe guardarse en el
historial. Y se guardará siempre y cuando el método devuelva verdadero.
PÁG. 49
method execute() is
saveBackup()
[Link] = [Link]()
[Link]()
return true

class PasteCommand extends Command is


method execute() is
saveBackup()
[Link]([Link])
return true

// La operación deshacer también es un comando.


class UndoCommand extends Command is
method execute() is
[Link]()
return false

// El historial global de comandos tan solo es una pila.


class CommandHistory is
private field history: array of Command

// El último dentro...
method push(c: Command) is
// Empuja el comando al final de la matriz del
// historial.

// ...el primero fuera.


method pop():Command is
// Obtiene el comando más reciente del historial.
PÁG. 50
// La clase editora tiene operaciones reales de edición de
// texto. Juega el papel de un receptor: todos los comandos
// acaban delegando la ejecución a los métodos del editor.
class Editor is
field text: string

method getSelection() is
// Devuelve el texto seleccionado.

method deleteSelection() is
// Borra el texto seleccionado.

method replaceSelection(text) is
// Inserta los contenidos del portapapeles en la
// posición actual.

// La clase Aplicación establece relaciones entre objetos. Actúa


// como un emisor: cuando algo debe hacerse, crea un objeto de
// comando y lo ejecuta.
class Application is
field clipboard: string
field editors: array of Editors
field activeEditor: Editor
field history: CommandHistory

// El código que asigna comandos a objetos UI puede tener


// este aspecto.
method createUI() is
PÁG. 51
// ...
copy = function() { executeCommand(
new CopyCommand(this, activeEditor)) }
[Link](copy)
[Link]("Ctrl+C", copy)

cut = function() { executeCommand(


new CutCommand(this, activeEditor)) }
[Link](cut)
[Link]("Ctrl+X", cut)

paste = function() { executeCommand(


new PasteCommand(this, activeEditor)) }
[Link](paste)
[Link]("Ctrl+V", paste)

undo = function() { executeCommand(


new UndoCommand(this, activeEditor)) }
[Link](undo)
[Link]("Ctrl+Z", undo)

// Ejecuta un comando y comprueba si debe añadirse al


// historial.
method executeCommand(command) is
if ([Link]())
[Link](command)

// Toma el comando más reciente del historial y ejecuta su método deshacer. Observa
que no conocemos la clase de ese comando. Pero no tenemos por qué, ya que el
comando sabe cómo deshacer su propia acción.
method undo() is

PÁG. 52
command = [Link]()
if (command != null)
[Link]()

4. REFERENCIAS
Creacionales
[Link]
[Link]
PÁG. 53
[Link]
[Link]
[Link]
%C3%B1o/Creational/Abstract%20Factory%20Design%20Pattern/
[Link]
[Link]
Estructurales
[Link]
[Link]
[Link]
[Link]
decorator/
[Link]
[Link]
73688bbd8e93
[Link]
De comportamiento
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]

PÁG. 54

También podría gustarte