Hallo vriend! Vandaag gaan we verder met het bestuderen van ontwerppatronen. In deze les gaan we het hebben over fabrieken. We bespreken het probleem dat dit patroon oplost en kijken naar een voorbeeld van hoe een fabriek je kan helpen bij het openen van een coffeeshop. Daarnaast geef ik je 5 eenvoudige stappen om een ​​fabriek te maken. Fabrieksontwerppatroon - 1 Om ervoor te zorgen dat we allemaal op dezelfde golflengte zitten en dat je dit concept snel begrijpt, moet je bekend zijn met de volgende onderwerpen:
  • Overerving op Java
  • Versmallen en verbreden van referentietypes in Java
  • Interactie tussen verschillende klassen en objecten.

Wat is een fabriek?

Met het fabrieksontwerppatroon kunt u het maken van objecten regelen. Het proces van het maken van een nieuw object is niet supereenvoudig, maar ook niet overdreven ingewikkeld. We weten allemaal dat we de newoperator nodig hebben om een ​​nieuw object te maken. Misschien lijkt het alsof er hier niets te controleren valt, maar dat is niet waar. Stel dat onze applicatie een bepaalde klasse heeft die veel afstammelingen heeft. Moeilijkheden kunnen optreden wanneer het nodig is om een ​​instantie van een specifieke klasse te maken, afhankelijk van bepaalde voorwaarden. Een fabriek is een ontwerppatroon dat helpt bij het oplossen van het probleem van het maken van verschillende objecten, afhankelijk van bepaalde omstandigheden. Hoe is dat voor een abstract concept? Dit wordt duidelijker en specifieker als we naar het onderstaande voorbeeld kijken.

Laten we verschillende soorten koffie bereiden

Stel dat we een coffeeshop willen automatiseren. We moeten ons programma leren hoe we verschillende soorten koffie kunnen zetten. Om dit te doen, maken we een koffieklasse en enkele afgeleide klassen om de soorten koffie weer te geven die we gaan bereiden: Americano, cappuccino, espresso en latte. Laten we beginnen met een algemene koffieles:

public class Coffee {
    public void grindCoffee(){
        // Grind the coffee
    }
    public void makeCoffee(){
        // Brew the coffee
    }
    public void pourIntoCup(){
        // Pour into a cup
    }
}
Vervolgens maken we de onderliggende klassen:

public class Americano extends Coffee {}
public class Cappuccino extends Coffee {}
public class CaffeLatte extends Coffee {}
public class Espresso extends Coffee {}
Onze klanten kunnen elk type koffie bestellen. Hun opdrachten moeten worden doorgegeven aan het programma. Dit kan op vele manieren, bijvoorbeeld met behulp van String. Maar een enumis hiervoor het beste. We maken een enumen definiëren opsommingsvelden die overeenkomen met de soorten koffie die kunnen worden besteld:

public enum CoffeeType {
    ESPRESSO,
    AMERICANO,
    CAFFE_LATTE,
    CAPPUCCINO
}
Geweldig. Laten we nu de code voor onze coffeeshop schrijven:

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;
    }
}
De orderCoffeemethode kan in twee delen worden verdeeld:
  1. Creatie van een specifiek exemplaar van koffie in een switchverklaring. Dit is waar een fabriek doet wat het doet: een specifiek type maken, afhankelijk van de omstandigheden.
  2. Voorbereiding - dit is het malen, brouwen en in een kopje gieten.
Dit is wat belangrijk is om te weten als u in de toekomst wijzigingen in de methode moet aanbrengen:
  1. De stappen van de bereiding zelf (malen, brouwen en in een kopje gieten) blijven ongewijzigd (daar rekenen we tenminste op).
  2. Maar het assortiment koffies kan veranderen. Misschien gaan we mokka maken... Frappu... Mochacci... Wat dan ook, een nieuwe soort koffie.
We kunnen er nu al redelijk zeker van zijn dat we in de toekomst wijzigingen zullen moeten aanbrengen in de switchverklaring van de methode. Het kan ook zijn dat in onze coffeeshop de orderCoffeemethode niet de enige plek is waar we verschillende soorten koffie gaan maken. Hierdoor zullen op meerdere plaatsen wijzigingen moeten worden doorgevoerd. U begrijpt waarschijnlijk al waar ik op doel. We moeten refactoren. Verplaats het blok dat verantwoordelijk is voor het maken van koffie naar een aparte klasse om twee redenen:
  1. De logica van het koffiezetten kunnen we op andere plekken hergebruiken.
  2. Als het assortiment verandert, hoeven we niet overal waar koffie wordt gemaakt de code te bewerken. Het is voldoende om onze code op slechts één plek te wijzigen.
Met andere woorden, de tijd is gekomen om een ​​fabriek op te zetten.

Het opzetten van onze eerste fabriek

Om dit te doen, maken we een nieuwe klasse die alleen verantwoordelijk is voor het maken van de noodzakelijke exemplaren van koffieklassen:

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;
    }
}
Gefeliciteerd! We hebben zojuist het fabrieksontwerppatroon in zijn eenvoudigste vorm (bijna) geïmplementeerd. Het had nog eenvoudiger kunnen zijn als we de createCoffeemethode statisch hadden gemaakt. Maar dan zouden we twee mogelijkheden verliezen:
  1. De mogelijkheid om SimpleCoffeeFactoryde methode over te nemen en te overschrijven createCoffee.
  2. De mogelijkheid om de vereiste fabrieksimplementatie aan onze lessen toe te voegen.
Trouwens, over implementatie gesproken... We moeten terug naar de coffeeshop en onze koffiefabriek toevoegen.

Een fabriek toevoegen aan de coffeeshop

Laten we de coffeeshopklasse herschrijven met behulp van een fabriek:

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;
    }
}
Uitstekend. Nu geven we een beknopte beschrijving van de algemene structuur van het fabrieksontwerppatroon.

In 5 stappen naar het openen van je eigen fabriek

Stap 1. Uw programma heeft een klasse met meerdere afstammelingen, zoals in onderstaand schema: Fabrieksontwerppatroon - 2Stap 2. U maakt een enummet een veld voor elke onderliggende klasse:

    enum CatType {
        LION,
        TIGER,
        FLUFFY
    }
Stap 3. Bouw je fabriek. Noem het CatFactory. Hier is de code:

class CatFactory {}
Stap 4. Creëer in je fabriek een createCatmethode die een CatTypeargument nodig heeft. Hier is de code:

    class CatFactory {
        public Cat createCat(CatType type) {
            
        }
    }
Stap 5. Schrijf in de hoofdtekst van de methode een switchinstructie die de enum-velden opsomt en een instantie van de klasse maakt die overeenkomt met de doorgegeven enumwaarde:

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;
        }
    }
Nu kun je een fabriek runnen als een baas. :)

Hoe te oefenen

Lezen is goed, code schrijven is nog beter. Als je naam een ​​even aantal letters heeft, probeer dan je eigen virtuele pizzeria te maken. Als je naam een ​​oneven aantal letters heeft, probeer dan een virtuele sushibar te maken. Als je geen naam hebt, heb je geluk gehad. Vandaag kunt u ontspannen.