Buna prietene! Astăzi vom continua să studiem modelele de design. În această lecție, vom vorbi despre fabrici. Vom discuta problema pe care o rezolvă acest tipar și vom privi un exemplu despre modul în care o fabrică vă poate ajuta să deschideți o cafenea. În plus, vă voi oferi 5 pași simpli pentru a crea o fabrică.
Pentru a vă asigura că suntem cu toții pe aceeași lungime de undă și că veți înțelege rapid acest concept, ar trebui să fiți familiarizați cu următoarele subiecte:
Pasul 2. Creați un

- Moștenirea în Java
- Restrângerea și extinderea tipurilor de referință în Java
- Interacțiunea dintre diferite clase și obiecte.
Ce este o fabrică?
Modelul de design din fabrică vă permite să controlați crearea obiectelor. Procesul de creare a unui nou obiect nu este super simplu, dar nici prea complicat. Știm cu toții că avem nevoie denew
operator pentru a crea un nou obiect. Poate se pare că nu există nimic de controlat aici, dar nu este adevărat. Să presupunem că aplicația noastră are o anumită clasă care are mulți descendenți. Dificultățile pot apărea atunci când este necesar să se creeze o instanță a unei clase specifice în funcție de anumite condiții. O fabrică este un model de design care ajută la rezolvarea problemei creării diferitelor obiecte în funcție de anumite condiții. Cum este asta pentru un concept abstract? Acest lucru va deveni mai clar și mai specific când ne uităm la exemplul de mai jos.
Să pregătim diverse tipuri de cafea
Să presupunem că vrem să automatizăm o cafenea. Trebuie să învățăm programul nostru cum să facem diferite tipuri de cafea. Pentru a face acest lucru, vom crea o clasă de cafea și câteva clase derivate pentru a reprezenta tipurile de cafea pe care le vom pregăti: Americano, cappuccino, espresso și latte. Să începem cu o clasă generală de cafea:
public class Coffee {
public void grindCoffee(){
// Grind the coffee
}
public void makeCoffee(){
// Brew the coffee
}
public void pourIntoCup(){
// Pour into a cup
}
}
În continuare, vom crea clasele sale secundare:
public class Americano extends Coffee {}
public class Cappuccino extends Coffee {}
public class CaffeLatte extends Coffee {}
public class Espresso extends Coffee {}
Clienții noștri pot comanda orice tip de cafea. Ordinele lor trebuie să fie transmise programului. Acest lucru se poate face în mai multe moduri, de exemplu, folosind String
. Dar an enum
este cel mai bun pentru asta. Vom crea enum
și vom defini câmpuri enumerate care corespund tipurilor de cafea care pot fi comandate:
public enum CoffeeType {
ESPRESSO,
AMERICANO,
CAFFE_LATTE,
CAPPUCCINO
}
Grozav. Acum să scriem codul pentru cafeneaua noastră:
public class CoffeeShop {
public Coffee orderCoffee(CoffeeType type) {
Coffee coffee = null;
switch (type) {
case AMERICANO:
coffee = new Americano();
break;
case ESPRESSO:
coffee = new Espresso();
break;
case CAPPUCCINO:
coffee = new Cappucсino();
break;
case CAFFE_LATTE:
coffee = new CaffeLatte();
break;
}
coffee.grindCoffee();
coffee.makeCoffee();
coffee.pourIntoCup();
System.out.println("Here's your coffee! Thanks! Come again!");
return coffee;
}
}
Metoda orderCoffee
poate fi împărțită în două părți:
- Crearea unei instanțe specifice de cafea într-o
switch
declarație. Aici o fabrică face ceea ce face - creează un anumit tip în funcție de condiții. - Pregătire - aceasta este măcinarea, prepararea și turnarea într-o ceașcă.
- Pașii implicați în prepararea în sine (măcinare, preparare și turnare într-o ceașcă) vor rămâne neschimbați (cel puțin contam pe asta).
- Dar sortimentul de cafele se poate schimba. Poate vom începe să facem mocha... Frappu... Mochacci... Oricum, un nou fel de cafea.
switch
. De asemenea, este posibil ca în cafeneaua noastră orderCoffee
metoda să nu fie singurul loc în care vom crea diferite tipuri de cafea. Ca urmare, modificările vor trebui făcute în mai multe locuri. Probabil că ați înțeles deja la ce vreau să ajung. Trebuie să refactorăm. Mutați blocul responsabil pentru crearea cafelei într-o clasă separată din două motive:
- Putem reutiliza logica de preparare a cafelei în alte locuri.
- Dacă sortimentul se schimbă, nu va trebui să edităm codul oriunde este creată cafeaua. Va fi suficient să ne schimbăm codul într-un singur loc.
Înființarea primei noastre fabrici
Pentru a face acest lucru, vom crea o nouă clasă care va fi responsabilă doar de crearea instanțelor necesare ale claselor de cafea:
public class SimpleCoffeeFactory {
public Coffee createCoffee(CoffeeType type) {
Coffee coffee = null;
switch (type) {
case AMERICANO:
coffee = new Americano();
break;
case ESPRESSO:
coffee = new Espresso();
break;
case CAPPUCCINO:
coffee = new Cappucino();
break;
case CAFFE_LATTE:
coffee = new CaffeLatte();
break;
}
return coffee;
}
}
Felicitări! Tocmai am implementat modelul de design din fabrică în cea mai simplă formă (aproape). Ar fi putut fi și mai simplu dacă am face createCoffee
metoda statică. Dar atunci am pierde două capacități:
- Abilitatea de a moșteni
SimpleCoffeeFactory
și de a anulacreateCoffee
metoda. - Capacitatea de a adăuga implementarea necesară din fabrică la clasele noastre.
Adăugarea unei fabrici la cafenea
Să rescriem clasa de cafenea folosind o fabrică:
public class CoffeeShop {
private final SimpleCoffeeFactory coffeeFactory;
public CoffeeShop(SimpleCoffeeFactory coffeeFactory) {
this.coffeeFactory = coffeeFactory;
}
public Coffee orderCoffee(CoffeeType type) {
Coffee coffee = coffeeFactory.createCoffee(type);
coffee.grindCoffee();
coffee.makeCoffee();
coffee.pourIntoCup();
System.out.println("Here's your coffee! Thanks! Come again!");
return coffee;
}
}
Excelent. Acum vom oferi o descriere concisă a structurii generale a modelului de proiectare din fabrică.
5 pași pentru a-ți deschide propria fabrică
Pasul 1. Programul dumneavoastră are o clasă cu mai mulți descendenți, ca în diagrama de mai jos:
enum
câmp cu un câmp pentru fiecare clasă copil:
enum CatType {
LION,
TIGER,
FLUFFY
}
Pasul 3. Construiește-ți fabrica. Sună-l CatFactory
. Iată codul:
class CatFactory {}
Pasul 4. În fabrica dvs., creați o createCat
metodă care preia un CatType
argument. Iată codul:
class CatFactory {
public Cat createCat(CatType type) {
}
}
Pasul 5. În corpul metodei, scrieți o switch
instrucțiune care enumeră câmpurile enumerate și creează o instanță a clasei care corespunde enum
valorii transmise:
class CatFactory {
public Cat createCat(CatType type) {
Cat cat = null;
switch (type) {
case LION:
cat = new Fluffy();
break;
case TIGER:
cat = new Tiger();
break;
case FLUFFY:
cat = new Lion();
break;
}
return cat;
}
}
Acum poți conduce o fabrică ca un șef. :)
GO TO FULL VERSION