CodeGym /Blog Java /Aleatoriu /Model de design din fabrică
John Squirrels
Nivel
San Francisco

Model de design din fabrică

Publicat în grup
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ă. Model de design din fabrică - 1 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:
  • 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 de newoperator 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 enumeste 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 orderCoffeepoate fi împărțită în două părți:
  1. Crearea unei instanțe specifice de cafea într-o switchdeclarație. Aici o fabrică face ceea ce face - creează un anumit tip în funcție de condiții.
  2. Pregătire - aceasta este măcinarea, prepararea și turnarea într-o ceașcă.
Iată ce este important de știut dacă trebuie să faceți modificări metodei în viitor:
  1. 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).
  2. Dar sortimentul de cafele se poate schimba. Poate vom începe să facem mocha... Frappu... Mochacci... Oricum, un nou fel de cafea.
Putem fi deja destul de încrezători că în viitor va trebui să facem modificări declarației metodei switch. De asemenea, este posibil ca în cafeneaua noastră orderCoffeemetoda 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:
  1. Putem reutiliza logica de preparare a cafelei în alte locuri.
  2. 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.
Cu alte cuvinte, a sosit momentul să înființăm o fabrică.

Î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 createCoffeemetoda statică. Dar atunci am pierde două capacități:
  1. Abilitatea de a moșteni SimpleCoffeeFactoryși de a anula createCoffeemetoda.
  2. Capacitatea de a adăuga implementarea necesară din fabrică la clasele noastre.
Apropo, vorbind de implementare... Trebuie să ne întoarcem la cafenea și să adăugăm fabrica noastră de cafea.

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: Model de design din fabrică - 2Pasul 2. Creați un enumcâ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 createCatmetodă care preia un CatTypeargument. Iată codul:

    class CatFactory {
        public Cat createCat(CatType type) {
            
        }
    }
Pasul 5. În corpul metodei, scrieți o switchinstrucțiune care enumeră câmpurile enumerate și creează o instanță a clasei care corespunde enumvalorii 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. :)

Cum să exersezi

Citirea este bună, scrierea codului este și mai bună. Dacă numele tău are un număr par de litere, încearcă să-ți creezi propria pizzerie virtuală. Dacă numele tău are un număr impar de litere, încearcă să creezi un sushi bar virtual. Dacă nu ai nume, ai avut noroc. Astăzi te poți relaxa.
Comentarii
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION