JavaSvet - otvorena java zajednica

 
glavna stranica arr2javasvet  english version arr2java.net

Abstract Factory

Igor Spasić
28 Maj 2004

Definicija

Abstract Factory patern definiše interfejs za kreiranje skupa objekata (međusobno zavisnih ili slične namene) bez specificiranja njihovih konkretnih klasa.

Opis

U procesu modelovanja aplikacija se prepoznaje slučaj kada jedna funkcionalnost može ili treba da se izvršava na više načina. Svaki od ovih načina izvršavanja je opisan svojim skupom klasa. Skupovi klasa se, posmatrano spolja, koriste na isti način, jer je, jasno, u pitanju ista funkcionalnost. Odluka koji se skup klasa koristi, tj. na koji način se izvršava funkcionalnost, se donosi u toku izvršavanja programa.

Primer koji se često koristi za opisivanje ovakvog slučaja je modelovanje grafičkog interfejsa (GUI) koji pruža različite izglede (look-and-feel) aplikacije. Funkcionalnost koju, na primer, obavlja jedno dugme (button) takvog sistema je ista u svim slučajevima, dok način na koji radi zavisi od trenutno izabranog izgleda. Korisnici mogu da promene trenutni izgled bilo kad u toku rada aplikacije.

Abstract Factory pruža mehanizam instanciranja zahtevanog skupa klasa, bez potrebe za odlučivanjem kod svake klase ponaosob i bez znanja o tome koja se konkretno klasa instancira, posmatrano sa strane korišćenja. U gornjem primeru bi svaki izgled (look-and-feel) imao svoj factory objekat, kako se obično naziva implementacija Abstract Factory-ja. Tako bi, na primer, postojale klase SilverGuiFactory i MinimalGuiFactory koje su zadužene za instanciranje odgovarajućih elemenata GUI-ja, u srebrnoj boji ili minimalnog dizajna, respektivno. Abstract Factory klasa bi mogla da ima apstraktni metod createButton(), čije bi implementacije kreirale i vraćale instance klasa SilverButton i MinimalButton, respektivno. Jasno, obe klase za dugme nasleđuju istu osnovnu apstraktnu klasu, recimo GuiButton, tako da na mestu korišćenja factory objekta uopšte nije bitno koja se instanca klase za dugme vraća. Klijent koristi metode definisane u interfejsu osnovne GuiButton klase, bez ikakve potrebe da zna sa kojom se implementacijom zaista radi.

Kao malo drugačiji primer može da posluži program koji kroz JDBC radi sa jednom od nekoliko podržanih baza. U ovom slučaju, factory objekti bi mogli biti OracleFactory, SapFactory, SybaseFactory itd. Abstract Factory klasa bi mogla da ima apstraktni metod getUserDbServices() koji vraća instance konkretne implementacije nekog UserDbServices interfejsa ili apstraktne klase. Pošto među bazama mogu da postoje razlike u SQL upitima za istu funkcionalnost, tako će OracleUserDbServices klasa 'znati' da radi sa Oracle bazom, SapUserDbServices sa SapDb bazom itd. Za razliku od prethodnog primera, ovde se odlučivanje sa kojom se bazom radi dešava na početku programa, ali odluka i dalje nije hard-kodovano u sors programa. Inače, ovaj primer za Abstract Factory predstavlja deo jednog drugog paterna: Data Access Objects (DAO).

Factory objekti, implementacije Abstract Factory klase, se često nazivaju i konkretnim factory objektima, pošto predstavljaju konkretne implementacije. Oni generišu tkzv. konkretne produkte, koji su svi tipa apstraktnog produkta. Konkretni factory objekti se obično kreiraju samo jednom u toku izvršavanja programa. Često se zbog toga i realizuju kao Singleton paterni. Sam Abstract Factory praktično delegira kreiranje produkata odgovarajućoj konkretnoj factory klasi.

UML dijagram

Učesnici

  • AbstractFactory - definiše interfejs za operacije koje kreiraju objekte tipa apstraktnog produkta
  • ConcreteFactory - implementira operacije za kreiranje konkretnog produkta
  • AbstractProduct - definiše interfejs za objekte tipa produkta
  • ConcreteProduct - definiše objekat konkretnog produkta koji će biti kreiran odgovarajućim konkretnim factory objektom
  • Client - korisnik interejsa definisanih u AbstractFactory i AbstractProduct klasama
  • Primer

    Primer koji se može downlodovati prikazuje korišćenje Abstract Factory paterna. Izvršni program primera svaki put na slučajan način određuje koji se konkretni factory objekat kreira, da bi se zatim on koristio kroz interfejs apstraktnog factory-ja. Proizvedeni konkretni produkti se koriste kroz interfejs apstraktnog produkta.