Hej vän! Idag kommer vi att fortsätta studera designmönster. I den här lektionen ska vi prata om fabriker. Vi kommer att diskutera problemet som detta mönster löser och titta på ett exempel på hur en fabrik kan hjälpa dig att öppna ett kafé. Dessutom kommer jag att ge dig 5 enkla steg för att skapa en fabrik.
För att vara säker på att vi alla är på samma våglängd och att du snabbt kommer att förstå detta koncept, bör du vara bekant med följande ämnen:
Steg 2. Du skapar ett

- Arv i Java
- Begränsning och breddning av referenstyper i Java
- Interaktion mellan olika klasser och objekt.
Vad är en fabrik?
Fabriksdesignmönstret låter dig styra skapandet av objekt. Processen att skapa ett nytt objekt är inte superenkel, men den är inte heller alltför komplicerad. Vi vet alla att vi behövernew
operatören för att skapa ett nytt objekt. Kanske verkar det som att det inte finns något att kontrollera här, men det är inte sant. Anta att vår applikation har en viss klass som har många ättlingar. Svårigheter kan uppstå när det är nödvändigt att skapa en instans av en specifik klass beroende på vissa förutsättningar. En fabrik är ett designmönster som hjälper till att lösa problemet med att skapa olika föremål beroende på vissa förutsättningar. Hur är det för ett abstrakt koncept? Detta kommer att bli tydligare och mer specifikt när vi tittar på exemplet nedan.
Låt oss förbereda olika typer av kaffe
Anta att vi vill automatisera ett kafé. Vi behöver lära vårt program hur man gör olika typer av kaffe. För att göra detta kommer vi att skapa en kaffeklass och några derivatklasser för att representera de typer av kaffe som vi kommer att tillaga: Americano, cappuccino, espresso och latte. Låt oss börja med en allmän kaffeklass:
public class Coffee {
public void grindCoffee(){
// Grind the coffee
}
public void makeCoffee(){
// Brew the coffee
}
public void pourIntoCup(){
// Pour into a cup
}
}
Därefter skapar vi dess underordnade klasser:
public class Americano extends Coffee {}
public class Cappuccino extends Coffee {}
public class CaffeLatte extends Coffee {}
public class Espresso extends Coffee {}
Våra kunder kan beställa vilken typ av kaffe som helst. Deras beställningar måste skickas till programmet. Detta kan göras på många sätt, till exempel genom att använda String
. Men en enum
är bäst för detta. Vi skapar ett enum
och definierar uppräkningsfält som motsvarar de typer av kaffe som kan beställas:
public enum CoffeeType {
ESPRESSO,
AMERICANO,
CAFFE_LATTE,
CAPPUCCINO
}
Bra. Låt oss nu skriva koden för vårt kafé:
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;
}
}
Metoden orderCoffee
kan delas upp i två delar:
- Skapande av en specifik instans av kaffe i ett
switch
uttalande. Det är här en fabrik gör vad den gör – skapa en specifik typ beroende på förhållandena. - Förberedelse - detta är malning, bryggning och upphällning i en kopp.
- Stegen i själva beredningen (malning, bryggning och upphällning i en kopp) kommer att förbli oförändrade (åtminstone vi räknar med detta).
- Men sortimentet av kaffe kan förändras. Vi kanske börjar göra mocka... Frappu... Mochacci... Vad som helst, en ny sorts kaffe.
switch
uttalande. Det är också möjligt att metoden i vårt kafé orderCoffee
inte kommer att vara den enda platsen där vi kommer att skapa olika typer av kaffe. Som ett resultat kommer förändringar att behöva göras på flera ställen. Du förstår säkert redan vad jag menar. Vi måste refaktorera. Flytta blocket som ansvarar för att skapa kaffe till en separat klass av två anledningar:
- Vi kan återanvända kaffebryggningslogiken på andra ställen.
- Om sortimentet ändras behöver vi inte redigera koden överallt där kaffe skapas. Det räcker med att ändra vår kod på bara ett ställe.
Vi sätter upp vår första fabrik
För att göra detta skapar vi en ny klass som endast kommer att ansvara för att skapa de nödvändiga instanserna av kaffeklasser:
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;
}
}
Grattis! Vi har precis implementerat fabriksdesignmönstret i dess enklaste form (nästan). Det kunde ha varit ännu enklare om vi gjort createCoffee
metoden statisk. Men då skulle vi förlora två förmågor:
- Förmågan att ärva
SimpleCoffeeFactory
och åsidosättacreateCoffee
metoden. - Möjligheten att lägga till den nödvändiga fabriksimplementeringen till våra klasser.
Lägger till en fabrik till kaféet
Låt oss skriva om kaféklassen med hjälp av en fabrik:
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;
}
}
Excellent. Nu ska vi ge en kortfattad beskrivning av den allmänna strukturen för fabriksdesignmönstret.
5 steg för att öppna din egen fabrik
Steg 1. Ditt program har en klass med flera ättlingar, som i diagrammet nedan:
enum
med ett fält för varje barnklass:
enum CatType {
LION,
TIGER,
FLUFFY
}
Steg 3. Bygg din fabrik. Kalla det CatFactory
. Här är koden:
class CatFactory {}
Steg 4. I din fabrik, skapa en createCat
metod som tar ett CatType
argument. Här är koden:
class CatFactory {
public Cat createCat(CatType type) {
}
}
Steg 5. Skriv i metodens brödtext en switch
sats som räknar upp enum-fälten och skapar en instans av klassen som motsvarar det godkända enum
värdet:
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 kan du driva en fabrik som en chef. :)
GO TO FULL VERSION