Tervezési minták a Swiftben: I. rész – Alkotói tervezési minta

A tervezési minták különböző megoldásokat jelentenek szoftverfejlesztési problémákra. Szoftvereket lehet építeni nélkülük is, de ez sokkal nehezebb.
Egy háromrészes sorozatot fogok kiadni a tervezési mintákkal kapcsolatban. Ebben a bejegyzésben a kreációs tervezési mintákról fogok beszélni.

A kreációs tervezési minták olyan tervezési minták, amelyek az objektumok létrehozási mechanizmusaival foglalkoznak, az objektumokat a helyzetnek megfelelő módon próbálják létrehozni. Az objektum létrehozásának alapvető formája tervezési problémákat eredményezhet, vagy a tervezéshez hozzáadott komplexitást eredményezhet. A kreációs tervezési minták úgy oldják meg ezt a problémát, hogy valamilyen módon irányítják ezt az objektum létrehozást.
Forrás: wikipedia.org

A következőkben az öt kreációs tervezési mintát fogjuk tárgyalni, és azt, hogy hogyan használhatjuk őket a swiftben.

Ez a fajta tervezési minta egy új objektum példányosítására szolgál egy meglévő, prototípusnak nevezett objektum klónozásával.

Az Apple osztály által megvalósított Fruit protokoll absztrakt klónozó függvényét látnánk, amely valójában magát az aktuális objektumot adja vissza.

Futtassuk le a fenti kódot a játszótéren.

// 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 //

– Egy objektum klónozásakor az objektum összes tulajdonságát átmásoljuk
egy másik objektumba.
– Ezt a tervezési mintát akkor kell használni, ha egy objektumot úgy kell létrehozni, hogy nem ismerjük az adott osztály hierarchiáját

A gyári módszer-minta

Ez a leggyakrabban használt tervezési minta. Alapvetően csak absztrahálja az objektum létrehozását.

Készítsünk egy FruitFactory nevű osztályt, amely visszaadja a szükséges objektum típusát.
Adjunk hozzá egy statikus metódust, amely paraméterként elfogad egy FruitType nevű enumot, és futásidőben visszaadja a szükséges objektumot.

A factory által visszaadott példányok Interface típusúak lennének(swift protokollban), amelyet minden factory jelölt osztálynak implementálnia kell.

A fenti kód futtatása után a játszótéren:

// 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

– A létrehozott objektum típusát futásidőben határozzuk meg.
– Ez a tervezési minta rugalmasabbá teszi a kódbázist új típusok hozzáadásához vagy eltávolításához.

Ez bevezet bennünket az interfészre, nem pedig az implementációra való programozás fogalmába.

Ez a tervezési minta interfészt biztosít kapcsolódó objektumcsaládok létrehozásához anélkül, hogy konkrét osztályaikat megadnánk. Ezeket gyakran a Factory Method mintával valósítják meg.

Van egy absztrakt gyárunk, a Furniture Factory a különböző termékek létrehozására. A konkrét gyári osztály Factory a Furniture Factory protokollt fogja megvalósítani.

A fenti kód futtatása.

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

– Az interfészt tárja fel, nem az implementációját
– Az absztrakt Factory olyan, mint egy protokoll, amit egy konkrét osztályon fogunk használni az objektumok létrehozásához

Builder Pattern

Ez a tervezési minta elválasztja az objektumok létrehozásának folyamatát a tényleges használatától.

Először deklarálunk egy absztrakt protokollt (vagy interfészt) a termék létrehozásához. Ebben az esetben ez a ShoeShop protokoll.
A Nike osztály egy konkrét építő, amely a termék létrehozásának folyamatát kapszulázza.

A rendező az objektumot az építő protokoll segítségével hozza létre. A rendezőt a ShoeShop protokollnak megfelelő objektummal kell inicializálni.

A kód futtatása után.

// 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"

– A Builder mintát használja a nyilvános API-k létrehozásakor, mert nem fedi fel a megvalósítás részleteit
– Elrejti a komplexitást. Egy összetett feladat mögött egyszerű API-t biztosít.

Singleton tervezési minta

A swiftben Singleton osztályokat definiálunk a static kulcsszó használatával. Ez azt jelenti, hogy az objektumot csak egyszer fogjuk példányosítani. A statikus tulajdonságok lustán inicializálódnak, és csak a meghíváskor lesznek instanciálva.
Ez az objektumnak csak egy példánya van, és a többi objektum globálisan használja.

Az Apple keretrendszerekben is láthatjuk a használatát:

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

A kód futtatása után

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

– A let kulcsszóval biztosítjuk, hogy a shredInstance értéke ne változzon
– Ne felejtsük el hozzáadni a private inicializálót, hogy más osztályok ne tudják meghívni az alapértelmezett inicializálóit

Itt a link a játszótéri fájlokra.

A fő ok, amiért a Creational Design Patternt használjuk, az az, hogy szétválasszuk az objektum létrehozásának logikáját a használatától. Segít csökkenteni a bonyolultságot azáltal, hogy az objektumokat ellenőrzött módon hozzuk létre a már említett, kipróbált & tesztelt megoldásokkal.

A viselkedési tervezési mintákról való olvasáshoz itt a link a blogra.

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé.