Abstrakti tehtaan kuvio - Abstract factory pattern
Abstrakti tehtaan malli tarjoaa tavan kapseloida ryhmän yksittäisiä tehtaita , joilla on yhteinen teema täsmentämättä niiden konkreettisia luokkia. Normaalikäytössä asiakasohjelmisto luo abstraktin tehtaan konkreettisen toteutuksen ja käyttää sitten tehtaan yleistä käyttöliittymää teemaan kuuluvien konkreettisten objektien luomiseen . Asiakas ei tiedä (tai hoidon), mitä konkreettisia esineitä se saa kaikista näistä sisäisten tehtaita, koska se käyttää ainoastaan yleisiä rajapinnat niiden tuotteita. Tämä malli erottaa objektijoukon toteutuksen yksityiskohdat niiden yleisestä käytöstä ja perustuu objektien kokoonpanoon, koska objektin luonti toteutetaan tehdasrajapinnassa paljastetuissa menetelmissä.
Esimerkki tästä olisi abstrakti tehdasluokka, DocumentCreatorjoka tarjoaa käyttöliittymät useiden tuotteiden (esim. createLetter()Ja createResume()) luomiseen . Järjestelmällä olisi mikä tahansa määrä johdettuja konkreettisia versioita DocumentCreatorluokan kaltaisesta FancyDocumentCreatortai ModernDocumentCreator, joista jokaisella on erilainen toteutus, createLetter()ja createResume()joka luo vastaavan objektin, kuten FancyLettertai ModernResume. Jokainen näistä tuotteista on johdettu yksinkertaisesta abstraktista luokasta, jonka kaltainen Lettertai Resumejosta asiakas on tietoinen. Asiakas koodi saisi asianmukaista oikeusasteen n DocumentCreatorja soittaa sen tehtaan menetelmiä . Jokainen tuloksena olevista objekteista luotiin samasta DocumentCreatortoteutuksesta ja niillä olisi yhteinen teema (ne kaikki olisivat hienoja tai moderneja esineitä). Asiakkaan on vain osattava käsitellä abstrakti Lettertai Resumeluokka, ei tarkkaa versiota, jonka se sai betonitehtaalta.
Tehdas on betoniluokan sijainti koodissa, johon objektit rakennetaan . Mallin käyttämisen tarkoituksena on eristää esineiden luominen niiden käytöstä ja luoda samankaltaisten esineiden perheitä tarvitsematta olla riippuvainen niiden konkreettisista luokista. Tämä mahdollistaa uusien johdettujen tyyppejä otetaan käyttöön ilman muutoksia koodi käyttää perustaa luokan .
Tämän mallin avulla on mahdollista vaihtaa konkreettisia toteutuksia muuttamatta niitä käyttävää koodia edes ajon aikana . Tämän mallin käyttö, kuten samankaltaisissa suunnittelumalleissa , voi kuitenkin johtaa tarpeettomaan monimutkaisuuteen ja ylimääräiseen työhön koodin alkuperäisessä kirjoittamisessa. Lisäksi korkeampi erottelu ja abstraktio voivat johtaa järjestelmiin, joita on vaikeampaa virheenkorjauksessa ja ylläpidossa.
Yleiskatsaus
Abstraktin tehtaan suunnittelumalli on yksi kahdestakymmenestä kolmesta tunnetusta GoF-suunnittelumallista, jotka kuvaavat toistuvien suunnitteluongelmien ratkaisemista joustavien ja uudelleenkäytettävien olio-ohjelmistojen suunnittelulle, toisin sanoen kohteille, jotka on helpompi toteuttaa, muuttaa, testata, ja käyttää uudelleen.
Abstraktin tehtaan suunnittelumalli ratkaisee esimerkiksi:
- Kuinka sovellus voi olla riippumaton siitä, miten sen objektit luodaan?
- Kuinka luokka voi olla riippumaton siitä, miten sen tarvitsemat objektit luodaan?
- Kuinka sukulaisia tai riippuvaisia esineitä voidaan luoda?
Objektien luominen suoraan luokan sisällä, joka vaatii objekteja, on joustamatonta, koska se sitouttaa luokan tiettyihin kohteisiin ja tekee mahdottomaksi muuttaa instanssia myöhemmin itsenäisesti luokasta (ilman, että sitä tarvitsee muuttaa). Se estää luokan uudelleenkäytön, jos muita esineitä tarvitaan, ja se vaikeuttaa luokan testaamista, koska todellisia esineitä ei voida korvata pilkko-objekteilla.
Abstraktin tehtaan suunnittelumalli kuvaa kuinka ratkaista tällaiset ongelmat:
- Kapseloi objektin luominen erilliseen (tehdas) objektiin. Eli määritä käyttöliittymä (AbstractFactory) objektien luomista varten ja toteuta käyttöliittymä.
- Luokka delegoi objektin luomisen tehdasobjektille sen sijaan, että luodaan objekteja suoraan.
Tämä tekee luokan riippumaton siitä, miten sen objektit luodaan (mitkä konkreettiset luokat ovat ilmentyneitä). Luokka voidaan määrittää tehdasobjektilla, jota se käyttää objektien luomiseen, ja vielä enemmän, tehdasobjekti voidaan vaihtaa ajon aikana.
Määritelmä
Abstraktin tehdasmallin ydin on "tarjota käyttöliittymä toisiinsa liittyvien tai riippuvaisten objektien perheiden luomiseksi määrittelemättä niiden konkreettisia luokkia".
Käyttö
Tehdas määrittää todellisen konkreettinen tyypin objekti on luotu, ja se on tässä, että objekti on todella luodaan (Java, esimerkiksi, että uusi operaattori ). Tehdas palauttaa kuitenkin vain abstraktin osoittimen luotuun konkreettiseen esineeseen .
Tämä eristää asiakaskoodin objektin luomisesta pyytämällä asiakkaita pyytämään tehdasobjektia luomaan halutun abstraktityypin objektin ja palauttamaan abstraktin osoittimen objektille.
Koska tehdas palauttaa vain abstraktin osoittimen, asiakaskoodi (joka pyysi objektia tehtaalta) ei tiedä juuri luodun objektin todellista konkreettista tyyppiä eikä sitä rasita. Abstrakti tehdas tietää kuitenkin konkreettisen esineen tyypin (ja siten betonitehtaan); esimerkiksi tehdas voi lukea sen kokoonpanotiedostosta. Asiakkaan ei tarvitse määrittää tyyppiä, koska se on jo määritetty määritystiedostossa. Tämä tarkoittaa erityisesti:
- Asiakas koodi eivät tunne lainkaan betonin tyyppiä , ei tarvitse sisällyttää mitään otsikkotiedostot tai luokan ilmoitusten liittyvät siihen. Asiakaskoodi käsittelee vain abstraktityyppiä. Konkreettisia objekteja luodaan tehtaalla, mutta asiakaskoodi käyttää tällaisia objekteja vain niiden abstraktin käyttöliittymän kautta .
- Uusien betonityyppien lisääminen tapahtuu muokkaamalla asiakaskoodia käyttämään eri tehtaita, joka on tyypillisesti yksi rivi yhdessä tiedostossa. Tehtaan eri luo sitten esineitä on eri konkreettien, mutta silti palauttaa osoittimen on saman abstraktin tyyppiä kuin ennen - näin eristävä asiakkaan koodin muutoksesta. Tämä on huomattavasti helpompaa kuin asiakaskoodin muokkaaminen uuden tyypin luomiseksi, mikä vaatii jokaisen sijainnin vaihtamisen koodissa, johon uusi objekti luodaan (samoin kuin varmistamalla, että kaikilla tällaisilla koodipaikoilla on myös tietoa uudesta betonityypistä, sisällyttämällä esimerkiksi konkreettisen luokan otsikkotiedoston). Jos kaikki tehdasobjektit on tallennettu globaalisti singleton- objektiin ja kaikki asiakaskoodit kulkevat singletonin läpi päästäksesi oikeaan tehtaaseen objektin luomista varten, tehtaiden vaihtaminen on yhtä helppoa kuin singleton-objektin vaihtaminen.
Rakenne
UML-kaavio
Edellä UML luokkakaavio , Clientluokka, joka vaatii ProductAja ProductBesineet ei instanssia ProductA1ja ProductB1luokat suoraan. Sen sijaan Clientviittaa AbstractFactorykäyttöliittymään objektien luomiseksi, mikä tekee Clientriippumaton siitä, miten objektit luodaan (mitkä konkreettiset luokat ovat instantioituja). Factory1Luokka toteuttaa AbstractFactoryrajapinnan käynnistämästä ProductA1ja ProductB1luokat.
UML kaavio esittää ajonaikaisen yhteisvaikutukset: esine puhelut on esine, joka luo ja palauttaa objektin. Tämän jälkeen puhelut päälle , joka luo ja palauttaa objektin.
ClientcreateProductA()Factory1ProductA1ClientcreateProductB()Factory1ProductB1
LePUS3-kaavio
Python- esimerkki
from abc import ABC, abstractmethod
from sys import platform
class Button(ABC):
@abstractmethod
def paint(self):
pass
class LinuxButton(Button):
def paint(self):
return "Render a button in a Linux style"
class WindowsButton(Button):
def paint(self):
return "Render a button in a Windows style"
class MacOSButton(Button):
def paint(self):
return "Render a button in a MacOS style"
class GUIFactory(ABC):
@abstractmethod
def create_button(self):
pass
class LinuxFactory(GUIFactory):
def create_button(self):
return LinuxButton()
class WindowsFactory(GUIFactory):
def create_button(self):
return WindowsButton()
class MacOSFactory(GUIFactory):
def create_button(self):
return MacOSButton()
if platform == "linux":
factory = LinuxFactory()
elif platform == "darwin":
factory = MacOSFactory()
elif platform == "win32":
factory = WindowsFactory()
else:
raise NotImplementedError(f"Not implemented for your platform: {platform}")
button = factory.create_button()
result = button.paint()
print(result)
Vaihtoehtoinen toteutus käyttämällä luokkia itse tehtaina:
from abc import ABC, abstractmethod
from sys import platform
class Button(ABC):
@abstractmethod
def paint(self):
pass
class LinuxButton(Button):
def paint(self):
return "Render a button in a Linux style"
class WindowsButton(Button):
def paint(self):
return "Render a button in a Windows style"
class MacOSButton(Button):
def paint(self):
return "Render a button in a MacOS style"
if platform == "linux":
factory = LinuxButton
elif platform == "darwin":
factory = MacOSButton
elif platform == "win32":
factory = WindowsButton
else:
raise NotImplementedError(f"Not implemented for your platform: {platform}")
button = factory()
result = button.paint()
print(result)
Katso myös
Viitteet
Ulkoiset linkit
- Tiivistelmä Tehtaan toteutus Java: ssa
-
Abstraktiin tehtaisiin liittyvät tiedotusvälineet Wikimedia Commonsissa - Tiivistelmä tehtaan UML-kaavio + muodollinen eritelmä LePUS3: ssa ja Class-Z: ssä (suunnittelukieli)
- Tiivistelmä tehdas Tiivistelmä tehtaan toteutusesimerkki
![Esimerkki UML-luokan ja sekvenssikaaviosta Abstract Factory -suunnittelukuvioon. [8]](/criselda-https-upload.wikimedia.org/wikipedia/commons/a/aa/W3sDesign_Abstract_Factory_Design_Pattern_UML.jpg)