Здравей приятел! Днес ще продължим да изучаваме дизайнерски модели. В този урок ще говорим за фабрики. Ще обсъдим проблема, който решава този модел, и ще разгледаме пример за това How една фабрика може да ви помогне да отворите кафене. Освен това ще ви дам 5 прости стъпки за създаване на фабрика.
За да сте сигурни, че всички сме на една и съща дължина на вълната и че бързо ще схванете тази концепция, трябва да сте запознати със следните теми:
Стъпка 2. Създавате поле

- Наследяване в Java
- Стесняване и разширяване на референтни типове в Java
- Взаимодействие между различни класове и обекти.
Какво е фабрика?
Фабричният шаблон за проектиране ви позволява да контролирате създаването на обекти. Процесът на създаване на нов обект не е супер прост, но не е и прекалено сложен. Всички знаем, че имаме нужда отnew
оператора, за да създадем нов обект. Може би изглежда, че тук няма Howво да се контролира, но това не е вярно. Да предположим, че нашето приложение има определен клас, който има много наследници. Трудности могат да възникнат, когато е необходимо да се създаде екземпляр от определен клас в зависимост от определени условия. Фабриката е модел на проектиране, който помага за решаването на проблема за създаване на различни обекти в зависимост от определени условия . Какво е това за абстрактно понятие? Това ще стане по-ясно и по-конкретно, когато разгледаме примера по-долу.
Да приготвим различни видове кафе
Да предположим, че искаме да автоматизираме кафене. Трябва да научим нашата програма How да прави различни видове кафе. За да направим това, ще създадем клас кафе и няколко производни класа, които да представят видовете кафе, които ще приготвяме: американо, капучино, еспресо и лате. Нека започнем с общ клас за кафе:
public class Coffee {
public void grindCoffee(){
// Grind the coffee
}
public void makeCoffee(){
// Brew the coffee
}
public void pourIntoCup(){
// Pour into a cup
}
}
След това ще създадем неговите дъщерни класове:
public class Americano extends Coffee {}
public class Cappuccino extends Coffee {}
public class CaffeLatte extends Coffee {}
public class Espresso extends Coffee {}
Нашите клиенти могат да поръчат всяHowъв вид кафе. Техните поръчки трябва да бъдат предадени на програмата. Това може да стане по много начини, например с помощта на String
. Но enum
е най-доброто за това. Ще създадем enum
и дефинираме полета enum, които съответстват на видовете кафе, които могат да бъдат поръчани:
public enum CoffeeType {
ESPRESSO,
AMERICANO,
CAFFE_LATTE,
CAPPUCCINO
}
Страхотен. Сега нека напишем codeа за нашето кафене:
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;
}
}
Методът orderCoffee
може да бъде разделен на две части:
- Създаване на конкретен екземпляр от кафе в
switch
изявление. Това е мястото, където фабриката прави това, което прави - създава специфичен тип в зависимост от условията. - Подготовка — това е смилането, варенето и наливането в чаша.
- Стъпките на самото приготвяне (смилане, варене и наливане в чаша) ще останат непроменени (поне на това разчитаме).
- Но асортиментът от кафета може да се промени. Може би ще започнем да правим мока... Фрапу... Мокачи... Каквото и да е, нов вид кафе.
switch
изявлението на метода. Също така е възможно в нашето кафене orderCoffee
методът да не е единственото място, където ще създаваме различни видове кафе. В резултат на това ще трябва да се направят промени на няколко места. Вероятно вече разбирате Howво имам предвид. Трябва да преработим. Преместете блока, отговорен за създаването на кафе, в отделен клас поради две причини:
- Можем да използваме повторно логиката за пequalsе на кафе на други места.
- Ако асортиментът се промени, няма да се налага да редактираме codeа навсякъде, където се създава кафе. Ще бъде достатъчно да променим codeа си само на едно място.
Създаване на нашата първа фабрика
За да направим това, ще създадем нов клас, който ще отговаря само за създаването на необходимите екземпляри на кафе класове:
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;
}
}
Честито! Току-що внедрихме модела на фабричния дизайн в най-простата му форма (почти). Можеше да бъде още по-просто, ако направихме createCoffee
метода статичен. Но тогава ще загубим две възможности:
- Възможността за наследяване
SimpleCoffeeFactory
и замяна наcreateCoffee
метода. - Възможност за добавяне на необходимата фабрична реализация към нашите класове.
Добавяне на фабрика към кафенето
Нека пренапишем класа кафене с помощта на фабрика:
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;
}
}
Отлично. Сега ще предоставим кратко описание на общата структура на шаблона за фабрично проектиране.
5 стъпки за отваряне на собствена фабрика
Стъпка 1. Вашата програма има клас с няколко наследници, Howто е показано на диаграмата по-долу:
enum
с поле за всеки дъщерен клас:
enum CatType {
LION,
TIGER,
FLUFFY
}
Стъпка 3. Изградете своята фабрика. Наречете го CatFactory
. Ето codeа:
class CatFactory {}
Стъпка 4. Във вашата фабрика създайте createCat
метод, който приема CatType
аргумент. Ето codeа:
class CatFactory {
public Cat createCat(CatType type) {
}
}
Стъпка 5. В тялото на метода напишете switch
израз, който изброява полетата enum и създава екземпляр на класа, който съответства на предадената enum
стойност:
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;
}
}
Сега можете да управлявате фабрика като шеф. :)
GO TO FULL VERSION