Ezen a ponton valószínűleg már találkozott tervezési mintákkal. Például a singleton .

Emlékezzünk vissza, mik azok a minták, miért van szükség rájuk, és mik azok az alkotási minták (egy példa). Tanulmányozunk egy új mintát is: a gyári módszert.

A szoftverfejlesztésben a tervezési minta egy megismételhető építészeti konstrukció, amely egy tervezési probléma megoldását jelenti valamilyen visszatérő kontextusban.

Jellemzően a minta nem egy végső megoldás, amely közvetlenül kóddá alakítható. Ez csak egy modellmegoldás egy problémára, amely különféle helyzetekben használható.

A kreatív minták olyan tervezési minták, amelyek az objektumok létrehozásának folyamatával foglalkoznak. Lehetővé teszik olyan rendszer létrehozását, amely független az objektumok létrehozásához, összeállításához és bemutatásához használt módszertől.

A gyári metódus egy olyan létrehozási tervezési minta, amely egy közös felületet határoz meg az objektumok létrehozásához egy szülőosztályban, lehetővé téve a leszármazottai számára, hogy létrehozzák ezeket az objektumokat. A létrehozáskor a leszármazottak meghatározhatják, hogy melyik osztályt hozzanak létre.

Milyen problémát old meg a minta?

Képzelje el, hogy úgy dönt, hogy létrehoz egy kézbesítési programot. Kezdetben futárokat fog bérelni autókkal, és aAutóobjektum egy szállító járművet ábrázol a programban. A futárok szállítják a csomagokat A pontból B pontba és így tovább. Könnyű peasy.

A program egyre népszerűbb. Vállalkozása növekszik, és szeretne új piacokra terjeszkedni. Például megkezdheti az élelmiszer- és áruszállítást is. Ebben az esetben az élelmiszert gyalog, robogóval, kerékpárral szállíthatják ki a futárok, de az áruszállításhoz teherautók szükségesek.

Most több dolgot kell nyomon követnie (mikor, kinek, mit és mennyit szállítanak ki), beleértve azt is, hogy az egyes futárok mennyit szállíthatnak. Az új szállítási módok eltérő sebességgel és kapacitással rendelkeznek. Ekkor észreveszi, hogy a legtöbb entitás a programban erősen kötődik aAutóosztály. Tudja, hogy ahhoz, hogy programja más szállítási módokkal is működjön, át kell írnia a meglévő kódbázist, és ezt minden alkalommal meg kell tennie, amikor új járművet ad hozzá.

Az eredmény egy szörnyű kód tele feltételes utasításokkal, amelyek a szállítás típusától függően különböző műveleteket hajtanak végre.

A megoldás

A gyári metódus mintája az objektumok létrehozását javasolja egy speciális gyári metódus meghívásával, nem pedig az új operátor közvetlen használatával. A gyári metódussal rendelkező osztály alosztályai módosíthatják az adott járművek létrehozott objektumait. Első pillantásra ez értelmetlennek tűnhet: egyszerűen áthelyeztük a konstruktorhívást a program egyik helyéről a másikra. Most azonban felülírhatja a gyári metódust egy alosztályban, hogy módosítsa a létrehozandó szállítás típusát.

Nézzük meg ennek a megközelítésnek az osztálydiagramját:

A rendszer működéséhez az összes visszaadott objektumnak közös felülettel kell rendelkeznie. Az alosztályok képesek lesznek különböző osztályú objektumokat előállítani, amelyek megvalósítják ezt az interfészt.

Például a Teherautó és Személygépkocsi osztályok a CourierTransport felületet egy kézbesítési módszerrel valósítják meg. Ezen osztályok mindegyike más-más módon valósítja meg a módszert: teherautók szállítanak árut, míg az autók élelmiszert, csomagokat stb. A TruckCreator osztály gyári metódusa egy teherautó objektumot, a CarCreator osztály pedig egy autó objektumot ad vissza.

A gyári metódus kliense számára nincs különbség ezen objektumok között, mivel valamiféle absztrakt CourierTransportként kezeli őket . Az ügyfél nagyon törődik azzal, hogy az objektumnak van egy módszere a szállításhoz, de az, hogy ez a módszer pontosan hogyan működik, nem fontos.

Megvalósítás Java nyelven:


public interface CourierTransport {
	void deliver();
}
public class Car implements CourierTransport {
	@Override
	public void deliver() {
    		System.out.println("The package is being delivered by car");
	}
}
public class Truck implements CourierTransport {
	@Override
	public void deliver() {
    		System.out.println("The freight is being delivered by truck");
	}
}
public abstract class CourierTransportCreator {
	public abstract CourierTransport createTransport();
}
public class CarCreator extends CourierTransportCreator {
	@Override
	public CourierTransport createTransport() {
    		return new Car();
	}
}
public class TruckCreator extends CourierTransportCreator {
	@Override
	public CourierTransport createTransport() {
    		return new Truck();
	}
}
 
public class Delivery {
	private String address;
	private CourierTransport courierTransport;
 
	public void Delivery() {
	}
 
	public Delivery(String address, CourierTransport courierTransport) {
    	this.address = address;
    	this.courierTransport = courierTransport;
	}
 
	public CourierTransport getCourierTransport() {
    		return courierTransport;
	}
 
	public void setCourierTransport(CourierTransport courierTransport) {
    		this.courierTransport = courierTransport;
	}
 
	public String getAddress() {
    		return address;
	}
 
	public void setAddress(String address) {
    		this.address = address;
	}
}
public static void main(String[] args) {
    	// Accept a new type of order from the database (pseudocode)
    	String type = database.getTypeOfDeliver();
 
    	Delivery delivery = new Delivery();
    	
    	// Set the transport for delivery
        delivery.setCourierTransport(getCourierTransportByType(type));
    	
    	// Make the delivery
        delivery.getCourierTransport().deliver();
 
	}
 
	public static CourierTransport getCourierTransportByType(String type) {
    	switch (type) {
        	case "CarDelivery":
            	return new CarCreator().createTransport();
        	case "TruckDelivery":
            	return new TruckCreator().createTransport();
        	default:
            	throw new RuntimeException();
	    }
	}
    

Ha új szállítási objektumot szeretnénk létrehozni, akkor a program automatikusan létrehoz egy megfelelő szállítási objektumot.

Mikor alkalmazzuk ezt a mintát?

1. Ha nem tudja előre azon objektumok típusait és függőségeit, amelyekkel a kódnak dolgoznia kell.

A gyári módszer elválasztja a szállítási módok előállításának kódját a szállítást használó kódtól. Ennek eredményeként az objektumok létrehozásának kódja a kód többi részének érintése nélkül bővíthető.

Például egy új típusú szállítás támogatásához létre kell hoznia egy új alosztályt, és meg kell határoznia benne egy gyári metódust, amely az új szállítás egy példányát adja vissza.

2. Ha rendszererőforrásokat szeretne megtakarítani a meglévő objektumok újrafelhasználásával, ahelyett, hogy újakat hozna létre.

Ez a probléma általában akkor fordul elő, ha erőforrás-igényes objektumokkal dolgozik, például adatbázis-kapcsolatokkal, fájlrendszerekkel stb.

Gondolja át a lépéseket, amelyeket meg kell tennie a meglévő objektumok újrafelhasználásához:

  1. Először is létre kell hoznia egy megosztott tárat az összes létrehozott objektum tárolására.

  2. Új objektum kérésekor meg kell nézni a tárat, és ellenőrizni kell, hogy az tartalmaz-e elérhető objektumot.

  3. Állítsa vissza az objektumot az ügyfélkódba.

  4. De ha nincsenek elérhető objektumok, hozzon létre egy újat, és adja hozzá a tárhoz.

Ezt a kódot el kell helyezni valahova, ahol nem zsúfolódik össze az ügyfélkód. A legkényelmesebb hely a konstruktor lenne, mivel ezekre az ellenőrzésekre csak az objektumok létrehozásakor van szükségünk. Sajnos a konstruktor mindig új objektumot hoz létre – nem tud visszaadni egy meglévő objektumot.

Ez azt jelenti, hogy egy másik módszerre van szükség, amely mind a meglévő, mind az új objektumokat visszaadja. Ez lesz a gyári módszer.

3. Ha engedélyezni szeretné a felhasználóknak, hogy bővítsék a keretrendszer vagy a könyvtár egyes részeit.

A felhasználók örökléssel bővíthetik keretosztályait. De hogyan lehet elérni, hogy a keretrendszer ezeknek az új osztályoknak az objektumait hozza létre a szabványosok helyett?

A megoldás az, hogy a felhasználók ne csak az összetevőket bővítsék ki, hanem az ezeket létrehozó osztályokat is. Ehhez pedig a létrehozó osztályoknak rendelkezniük kell konkrét, definiálható létrehozási metódusokkal.

Előnyök

  • Leválaszt egy osztályt az adott szállítási osztályokról.
  • Egy helyen tartja a szállítási módok létrehozásához szükséges kódot, így a kód könnyebben karbantartható.
  • Leegyszerűsíti az új közlekedési módok hozzáadását a programhoz.
  • A nyitott-zárt elvet valósítja meg.

Hátrányok

Nagy párhuzamos osztályhierarchiákhoz vezethet, mivel minden termékosztálynak saját alkotói alosztályával kell rendelkeznie.

Foglaljuk össze

Megismerte a gyári módszer mintáját, és látott egy lehetséges megvalósítást. Ezt a mintát gyakran használják különféle könyvtárakban, amelyek objektumokat biztosítanak más objektumok létrehozásához.

Használja a gyári metódusmintát, ha egyszerűen szeretne új objektumokat hozzáadni meglévő osztályok alosztályaihoz, hogy kölcsönhatásba lépjen a fő üzleti logikával, és ne duzzadjon fel a kódban a különböző kontextusok miatt.