Patrones de diseño en Swift: Parte I – Patrón de Diseño Creativo

Los patrones de diseño son diferentes soluciones a los problemas de ingeniería de software. Se pueden construir softwares sin ellos pero es mucho más difícil.
Estaré publicando una serie de tres partes con respecto a los patrones de diseño. En este post, voy a hablar de los patrones de diseño de creación.

Los patrones de diseño de creación son patrones de diseño que se ocupan de los mecanismos de creación de objetos, tratando de crear objetos de una manera adecuada a la situación. La forma básica de creación de objetos podría resultar en problemas de diseño o en una complejidad añadida al diseño. Los patrones de diseño de creación resuelven este problema controlando de alguna manera esta creación de objetos.
Fuente: wikipedia.org

Aquí vamos a hablar de los cinco patrones de diseño de creación y de cómo podemos utilizarlos en swift.

Este tipo de patrón de diseño se utiliza para instanciar un nuevo objeto clonando un objeto existente llamado prototipo.

Vamos a ver una función abstracta de clonación del protocolo Fruit implementada por la clase Apple que en realidad devuelve el propio objeto actual.

Ejecutamos el código anterior en el playground.

// Create a prototype
let prototype = Apple(count: 4)// Create a copy of existing object
let redApple: Apple = prototype.clone() as! Apple
redApple.count // 4// add own properties
redApple.set(price: "")
redApple.price // // Create a copy of existing object
let greenApple: Apple = prototype.clone() as! Apple
greenApple.count // 4// add own properties
greenApple.set(price: "")
greenApple.price //

– Cuando se clona un objeto, todas las propiedades de ese objeto se copian a
otro objeto.
– Este patrón de diseño se debe utilizar cuando se necesita crear un objeto sin conocer la jerarquía de esa clase

El patrón de métodos de fábrica

Es el patrón de diseño más utilizado. Básicamente, sólo abstrae la creación de un objeto.

Crea una clase llamada FruitFactory que devuelve el tipo del objeto que se necesita.
Añade un método estático que acepta un enum llamado FruitType como parámetro y devuelve el objeto que se necesita en tiempo de ejecución.

Cualquier instancia devuelta por la fábrica sería de tipo Interface(en el protocolo swift) que cualquier clase candidata a fábrica debe haber implementado.

Después de ejecutar el código anterior en el playground:

// get the object of class Orange from the FruitFactory class
let orange = FruitFactory.getFruit(forType: .orange)
orange?.getPrice() // "
orange?.getCount() // 2// get the object of class Grapes from the FruitFactory class
let grapes = FruitFactory.getFruit(forType: .grapes)
grapes?.getPrice() // ""
grapes?.getCount() // 1

– El tipo del objeto creado se determina en tiempo de ejecución.
– Este patrón de diseño hace que el códigobase sea más flexible para añadir o eliminar nuevos tipos.

Esto nos introduce en el concepto de programa a una interfaz, no a una implementación.

Este patrón de diseño proporciona una interfaz para crear familias de objetos relacionados sin especificar sus clases concretas. Se suelen implementar con el patrón Método Fábrica.

Tenemos una fábrica abstracta llamada Fábrica de Muebles para crear diferentes productos. La clase concreta Fábrica estará implementando el protocolo Fábrica de Muebles.

Ejecutando el código anterior.

// create MyChair class object
let chair = Factory.createChair()
chair.count() // 4// create MyTable class object
let table = Factory.createTable()
table.count() // 1

– Revela la interfaz, no su implementación
– Abstract Factory es como un protocolo que usaremos en una clase concreta para crear objetos

Patrón Constructor

Este patrón de diseño separa el proceso de creación de objetos de su uso real.

Primero declaramos un protocolo abstracto(o interfaz) para crear el producto. En este caso es el protocolo ShoeShop.
La clase Nike es un constructor concreto para encapsular el proceso de creación del producto.

Director crea el objeto utilizando el protocolo del constructor. Director debe ser inicializado con el objeto que se ajusta al protocolo de ShoeShop.

Después de ejecutar el código.

// create a nike object
let nike = Nike()// instantiate Director with nike object
let director = Director(shoeShop: nike)// encapsulated the process of producing the nike product
director.produce() // "Shoe produced"

– Utiliza el patrón Builder cuando construye APIs públicas porque no revela los detalles de la implementación
– Oculta la complejidad. Proporciona una API simple detrás de una tarea compleja.

Patrón de diseño Singleton

En swift definimos las clases Singleton utilizando la palabra clave static. Significa que el objeto va a ser instanciado sólo una vez. Las propiedades estáticas se inicializan de forma perezosa y no se instanciarán hasta que sean llamadas.
Sólo hay una copia de este objeto y es utilizada por los demás objetos de forma global.

También podemos ver el uso en los frameworks de Apple:

// Shared url session
let urlSession = URLSession.shared// user defaults
let userDefaults = UserDefaults.standard

Después de ejecutar el código

Vehicle.sharedInstance.getName() // "Car"

– Usamos la palabra clave let para asegurarnos de que el valor de shredInstance no cambiará
– No olvides añadir el inicializador privado para evitar que otras clases llamen a sus inicializadores por defecto

Aquí tienes el enlace a los archivos del playground.

La razón principal por la que usamos el Patrón de Diseño de Creación es para desacoplar la lógica de creación de un objeto de su uso. Ayuda a reducir las complejidades mediante la creación de objetos de una manera controlada con soluciones probadas &ya mencionadas.

Para leer sobre los patrones de diseño de comportamiento, aquí está el enlace al blog.

Deja una respuesta

Tu dirección de correo electrónico no será publicada.