предисловие
Только лысина может стать сильнее
Оглядываясь назад на фронт:
- Объясни своей девушке, что такое прокси-режим
- Режим упаковки так прост
- Сколько способов вы знаете шаблон singleton?
Вчера я написал шаблон singleton, а сегодня пришло время написать шаблон factory~
фабричный образец яя лично думаю, что это сложнее понять, если вы общались | слышали | видели эту модель, ученики, скорее всего, подумают: я самnew
Объект получается просто прекрасным, простым и быстрым. Вам нужна ваша заводская выкройка? Чтобы построить фабрику, нужно много кода~
Много информации в интернете разъясняет: преимущество заводской модели в том, чторазъединение. я верю всемразъединениеЭто слово не является незнакомым, так в чем же польза от развязки?
эта статьяПопробуйте объяснитьЗачем использовать фабричный шаблон, каковы преимущества использования фабричного шаблона и каковы различия между тремя формами, полученными из фабричного шаблона~~
Тогда давайте начнем Если что-то не так, я надеюсь простить меня много, и не стесняйтесь поправлять меня в области комментариев!
Обзор фабричного шаблона
В книге «Дзен шаблонов проектирования» фабричный шаблон разделен на две главы:
- Шаблон фабричного метода
- (ps: в нем упоминается простой заводской шаблон)
- Абстрактный заводской узор
Большая часть информации в интернете делит заводскую модель натрисвоего рода:
- Простой/статический заводской шаблон
- Шаблон фабричного метода
- Абстрактный заводской узор
Прочитав приведенное выше описание, вы хотите меня убить, что за птица? Не волнуйтесь, я расскажу о них один за другим ниже~
1.1 Зачем использовать заводской шаблон?
Подумайте, почему мы используем шаблон factory? Вот мой простой пример:
Мы будем часто использовать операцию файлового ввода-вывода, поэтому объект BufferedReaderчасто создаютиз:
// 创建一个BufferedReader对象
BufferedReader bf = new BufferedReader(new FileReader(new File("aa.txt")));
Ты сказал беда? На самом деле это не хлопотно, всего одна строчка кода, где беда~ Если студенты, не знакомые с IO-потоками, не настолько умны, создание BufferedReader может быть следующим кодом:
File file = new File("aa.txt");
FileReader fileReader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(fileReader);
Ты сказал беда? На самом деле это не хлопотно, не правда ли, всего три строчки кода, в чем беда~ Если это приложениеИспользуется во многих классахДля объектов BufferedReader эти три строки кода записываются в каждом классе. Тогда вы говорите беда? Это должно быть хлопотно, мне все еще нужно подумать об этом...
Видно, что для создания объекта BufferReader требуется объект FileReader, а для объекта FileReader требуется объект File. ТотСоздание этого объекта BufferReader более проблематично(Код не хлопотный, но хлопотный со структурной точки зрения)!
Хотя это более хлопотно, мы все же можем его использовать, и мы можем его использовать! Итак, мы пошли писать код.Теперь есть три класса, которым нужно читать и записывать файлы, поэтому у них такой код:
public class FileOperateA {
public static void main(String[] args) throws FileNotFoundException {
File file = new File("aa.txt");
FileReader fileReader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(fileReader);
// 读写文件....
}
}
В это время: Выше сказано, я хочуИзмените на LineNumberReader для чтения и записи, есть этот спрос! Итак, что мы можем сделать как кодировщики? Отчаялся и должен это сделать.
- Парень, который не знаком с IDE, просто поменял BufferedReader на LineNumberReader один за другим, теперь только 3 класса используют BufferedReader, и только 6 раз. (ps: Что, если он используется во многих местах?)
- Парень, знакомый с IDE, заменит рефакторинг глобально, вот и все!
эй, писать код - куча дерьма... есть ли способ сделатьСоздание объектов стало прощеиМожет быть очень удобно при изменении объектовШерстяная ткань?
- Эй, заводской режим подойдет.
снова изОбъектно-ориентированная перспектива: Не слишком ли сложно для меня создать BufferReader для класса, который манипулирует файлами? (обязанности не распределены должным образом)
- Передача на фабрику создания объектов очень объектно-ориентирована!
1.2 Испытайте заводской режим
Что такое фабрика? Вся наша продукция передается на завод для производства! Откуда взялся iPhone 5s, которым я сейчас пользуюсь? Собран на заводе Foxconn. Нужно ли мне знать, как iphone5s собирается в Foxconn? ненужный.
Давай, давайте переделаем приведенный выше пример. Сначала мы создаем фабричный класс, который можетСоздание объектов Reader!
// 创建Reader对象的工厂
public class ReaderFactory {
public static Reader getReader() throws FileNotFoundException {
File file = new File("aa.txt");
FileReader fileReader = new FileReader(file);
BufferedReader reader = new BufferedReader(fileReader);
return reader;
}
}
Затем нам нужно получить объект BufferReaderВор простойв настоящее время:
public class FileOperateA {
public static void main(String[] args) throws FileNotFoundException {
//-------我有工厂了,还用自己搞吗?不用了!
//File file = new File("aa.txt");
//FileReader fileReader = new FileReader(file);
//BufferedReader bufferedReader = new BufferedReader(fileReader);
//-------我有工厂了,还用自己搞吗?不用了!
// 用工厂来创建出对象
Reader reader = ReaderFactory.getReader();
// 读写文件....
}
}
завод будет намПроцесс созданного объекта заблокирован!
На данный момент я хочу перейти на LineNumberReader, как играть? существуетМеняй на заводеДостаточно:
наш абонентFileOperateA|FileOperateB|FileOperateC
Эти классы вообще не нужно менять!
1.3 Преимущества использования фабричных методов
Из приведенного выше опыта фабричного шаблона мы можем видеть, что:
- Мы изменили конкретный класс реализации, предназначенный для клиента (вызывающего)вообще без модификации.
- если мы используем
new
способ создания объекта, то мы говорим:new
Выходящий объект и текущий клиент (вызывающий)связь!- То есть текущий клиент (вызывающий)зависит отэто
new
вне объекта!
- То есть текущий клиент (вызывающий)зависит отэто
В этом преимущество развязки!
Позвольте мне записать код, который я написал в предыдущей практике:
У меня есть DaoFactory, логика очень простаСпециальное создание объектов Даода~
Затем на уровне службы вы можетеИспользуйте фабрику для инициализации желаемого объекта Dao~
На данный момент наши объекты Службы и Даонизкое сцеплениеда~
- Всеможет не увидеть никакой выгоды, также есть много строк или что-то в этом роде~~
В слоях Service и Controller я также получил ServiceFactory.Согласно потребностям бизнеса на тот момент (добавление разрешений), яОчень гибкий при создании сервисовв настоящее время:
2. Как использовать заводской шаблон
Как я уже говорил в начале, фабричный паттерн можно разделить на три категории:
- Простой/статический заводской шаблон
- Шаблон фабричного метода
- Абстрактный заводской узор
Далее я покажу разницу между каждым заводским режимом один за другим ~
Все три режима начинаются с:Java3y хочет купить пример для объяснения~
2.1 Шаблон фабричного метода
Многие блоги объясняют фабричный шаблон в следующем порядке: простой/статический фабричный шаблон, фабричный метод и абстрактный фабричный шаблон. Я думаю, что легче понять порядок в книге, потому что простой/статический фабричный шаблон находится в шаблоне фабричного метода.уменьшать, абстрактный фабричный шаблон является расширением фабричного метода.усилить.
- Итак, сначала я расскажу о шаблоне фабричного метода.
Java3y скучно писать код каждый день, я хочу купить домашнее животное, чтобы сопровождать меня. Так чтоСходите в зоомагазин, чтобы увидеть домашних животных~~~
Как зоомагазин, он утверждает, что у него есть все виды домашних животных! Итак, когда хозяин дал объявление, он сказал: Мой зоомагазинлюбой питомец!
Так родилась фабрика по производству питомцев~
// 号称什么宠物都有
public interface AnimalFactory {
// 可以获取任何的宠物
Animal createAnimal();
}
Конечно, обычные домашние животные должны быть в наличии, и некоторые из них помещаются в магазин, чтобы заполнить витрину, а некоторые специальные домашние животные скажут покупателям, что нужно время, чтобы запастись ~
- Итак, у нас есть фабрика по постройке кошек и собак (наследует фабрику для всех питомцев)
Фабрика кошек:
// 继承着宠物工厂
public class CatFactory implements AnimalFactory {
@Override
// 创建猫
public Animal createAnimal() {
return new Cat();
}
}
То же самое касается собачьей фабрики:
// 继承着宠物工厂
public class DogFactory implements AnimalFactory {
// 创建狗
@Override
public Animal createAnimal() {
return new Dog();
}
}
Ну, есть еще наши классы сущностей: кошки, собаки, животные (полиморфизм: кошки и собаки — это животные, которые могут быть напрямую представлены животными)
Класс животных:
public abstract class Animal {
// 所有的动物都会吃东西
public abstract void eat();
}
Класс сущности кошки:
public class Cat extends Animal {
// 猫喜欢吃鱼
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
Класс сущности собаки:
public class Dog extends Animal {
// 狗喜欢吃肉
@Override
public void eat() {
System.out.println("狗吃肉");
}
}
Итак, теперь Java3y хочет собаку и сказал владельцу зоомагазина, что владелец зоомагазина пошел искать собаку и вернулся:
// 去找狗工厂拿一只狗过来
AnimalFactory f = new DogFactory();
// 店主就拿到了一只狗给Java3y
Animal a = f.createAnimal();
a.eat();
System.out.println("关注公众号:Java3y");
Итак, теперь Java3y хочет кошку и сказал владельцу зоомагазина, что владелец зоомагазина пошел искать кошку и вернулся:
// 去找猫工厂拿一只猫过来
AnimalFactory ff = new CatFactory();
// 店主就拿到了一只猫给Java3y
Animal aa = ff.createAnimal();
aa.eat();
System.out.println("关注公众号:Java3y");
Что, если Java3y скажет, что сейчас хочет ящерицу? без проблем, лавочникПостроить фабрику ящерицЭто хорошо~~
// 要买蜥蜴..
AnimalFactory fff = new LizardFactory();
Animal aaa = ff.createAnimal();
aaa.eat();
преимущество:
- 1: Клиент не должен нести ответственность за создание объекта,Уточнены обязанности каждого класса
- 2: если естьдобавлены новые объекты,нужно всего лишьДобавьте класс бетона и класс бетонной фабрикиПросто
- 3:Не влияет на существующий код, последующее обслуживание упрощается, а масштабируемость системы повышается
недостаток:
- 1: требует дополнительного кодирования и увеличивает рабочую нагрузку
Диаграмма класса фабричного метода:
2.2 Простой/статический заводской шаблон
Теперь бизнес зоомагазина не очень хорош, он известен как «все домашние животные», это раздуто~~ Итак, владелецПродаются только два обычных питомца.
- Поскольку есть только два вида домашних животных, нет необходимости иметь «фабрику кошек» и «фабрику собак», достаточно одной фабрики кошек и собак!
Итак, наша фабрика выглядит так:
public class AnimalFactory {
public static Dog createDog() {
return new Dog();
}
public static Cat createCat() {
return new Cat();
}
// 外界想要猫要狗,这里创建就好了
public static Animal createAnimal(String type) {
if ("dog".equals(type)) {
return new Dog();
} else if ("cat".equals(type)) {
return new Cat();
} else {
return null;
}
}
}
Три сущности остаются прежними (животное, кошка, собака) …
Затем, когда Java3y идет в зоомагазин, чтобы купить кошек и собак, он говорит боссу, что я хочу кошек и собак:
// 拿到狗
Animal A = AnimalFactory.createAnimal("dog");
A.eat();
// 拿到猫
Animal C = AnimalFactory.createAnimal("cat");
C.eat();
Теперь возникает вопрос:
- 1: Я хочу свинью,Но в моем фабричном классе нет свиней
- 2: я пойдуизменятькод, который может создавать объекты свиньи
- 3: Далее, я хочу других животных
- 4: я все еще долженизменятькод
- 5...................
- 6: Это недостаток простого фабричного класса:Когда требования изменятся, я изменю код.
Преимущества простого фабричного класса также очевидны: IСоздание объектов на бетонном заводе, объем кода небольшой.
2.3 Шаблон абстрактной фабрики
Шаблон абстрактной фабрики более сложен, мыОбщие приложения не могут быть написаны. Позвольте мне сначала кратко описать требования:
- Сейчас это очень популярно, а еще в кошачьей и собачьей индустрии витает «гендерный ветер».
- Некоторым нравится мужчина
- некоторые как матери
Тогда наши кошки и собаки бывают всех полов, мужского или женского пола~~
- Раньше мы открывали фабрику для каждого животного в режиме фабричного метода.Если животных слишком много, будет много фабрик~
- Итак, теперь мы можемизвлекать: Каждое животное либо самец, либо самка~
- Так что у нас достаточно двух заводов!
Конкретный код таков:
Наша самая большая фабрика по-прежнему определяет, какое животное создается
public interface AnimalFactory {
Animal createDog();
Animal createCat();
}
Фабрика по созданию кошек и собак женского пола:
public class FemaleAnimalFactory implements AnimalFactory {
// 生产母狗和母猫
@Override
public Animal createDog() {
return new FemaleDog();
}
@Override
public Animal createCat() {
return new FemaleCat();
}
}
Фабрика по созданию котов и собак:
public class MaleAnimalFactory implements AnimalFactory {
// 生产公狗和公猫
@Override
public Animal createDog() {
return new MaleDog();
}
@Override
public Animal createCat() {
return new MaleCat();
}
}
ЭтоОбщее поведение, которое есть у всех животных:
public abstract class Animal {
// 所有的动物都会吃东西
public abstract void eat();
// 所有的动物都有性别
public abstract void gender();
}
Вот общее поведение, которое есть у всех кошек:
public abstract class Cat extends Animal {
// 猫喜欢吃鱼
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
Вот общее поведение, которое есть у всех собак:
public abstract class Dog extends Animal {
// 狗喜欢吃肉
@Override
public void eat() {
System.out.println("狗吃肉");
}
}
Кошки делятся на кошек-самцов и кошек-самок. Собаки делятся на самцов и самок:
public class FemaleCat extends Cat {
public void gender() {
System.out.println("I am a female Cat");
}
}
.....
Проще говоря: фабрика паттерна фабричный метод заключается в созданиисвоего родапродукты, а абстрактная фабрика должна создаватьодин типпродукт.
- Класс продуктов, который мы называемСемейство продуктов.
- Кошки — это один вид, как и собаки. Итак, AnimalFactory определяет два типа продуктов --->
Animal createDog();
иAnimal createCat();
- Кошки — это один вид, как и собаки. Итак, AnimalFactory определяет два типа продуктов --->
- продуктструктура наследованияназови этокачество продукта.
- Все животные едят, и все они занимаются сексом, что является наиболее распространенным. Итак, Animal определяет два абстрактных метода:
public abstract void eat();
иpublic abstract void gender();
- Все собаки едят мясо, поэтому собака сделала это возможным
eat()
метод- Собаки делятся на собак мужского пола и собак женского пола, поэтому определены два класса FemaleDog и MaleDog, чтобы наследовать Dog и реализовать
gender()
метод
- Собаки делятся на собак мужского пола и собак женского пола, поэтому определены два класса FemaleDog и MaleDog, чтобы наследовать Dog и реализовать
- Все коты едят рыбу, поэтому это сделал Кот
eat()
метод- Кошки делятся на кошек мужского пола и кошек женского пола, поэтому определены два класса FemaleCat и MaleCat, чтобы наследовать Cat и реализовать
gender()
метод
- Кошки делятся на кошек мужского пола и кошек женского пола, поэтому определены два класса FemaleCat и MaleCat, чтобы наследовать Cat и реализовать
- Все животные едят, и все они занимаются сексом, что является наиболее распространенным. Итак, Animal определяет два абстрактных метода:
- Конкретный заводПроизводство для множественной иерархии продуктов.
- Итак, FemaleAnimalFactory определяет
createDog()
иcreateCat()
Рождение самок собак и кошек - Итак, MaleAnimalFactory определяет
createDog()
иcreateCat()
Производство кобелей и обыкновенных кошек
- Итак, FemaleAnimalFactory определяет
- Найдите женскую фабрику для создания женских кошек и собак и мужскую фабрику для создания самцов кошек и самцов собак.
public static void main(String[] args) {
// 需要性别为母的就去找母工厂
AnimalFactory af = new FemaleAnimalFactory();
// 需要一只母猫
af.createCat().gender();
// 需要一只母狗
af.createDog().gender();
System.out.println("-------------关注公众号:Java3y-------------------------");
// 需要性别为公的就去找公工厂
AnimalFactory aff = new MaleAnimalFactory();
// 需要一只公狗
aff.createDog().gender();
// 需要一只公猫
aff.createCat().gender();
}
Эффект:
Вот диаграмма классов абстрактного шаблона factory:
Абстрактный фабричный шаблонЕще один уровень абстракции, уменьшающий количество фабрик.
Недостатки абстрактных фабрик также очевидны:
- трудныйРасширить семейство продуктов---> Если я снова хочу домашних свиней
- Затем мне нужно изменить классы AnimalFactory, FemaleAnimalFactory и MaleAnimalFactory~
3. Резюме
В целом мыИспользуйте простой заводской шаблон больше, режим фабричного режима будет иметь относительно большой объем кода, а абстрактный фабричный режим будет использоваться только тогда, когда бизнес относительно большой (если у вас есть метод лучшего понимания, вы можете оставить сообщение в области комментариев и обменяться идеи вместе~~)
- Также отлично использовать заводской режим с отражением~
Использованная литература:
- Дзен шаблонов проектирования
- Wangjingxin.top/2016/10/27/…--[Оригинал] Серия шаблонов проектирования (IX) - Шаблон абстрактной фабрики
- Ууху. Call.com/question/24…-- Какая польза от фабричного шаблона проектирования?
- blog.CSDN.net/lemon_tree1…-- Шаблон проектирования Java - заводской шаблон
- блог woo woo woo.cn на.com/secretly/afraid/48…-- Подробное объяснение фабричного шаблона шаблонов проектирования (простая фабрика + фабричный метод + абстрактная фабрика)
- woo woo woo.cn blog on.com/Poisson note…-- заводской режим
Если в статье есть какие-либо ошибки, пожалуйста, поправьте меня, и мы сможем общаться друг с другом. Учащиеся, привыкшие читать технические статьи в WeChat и желающие получить больше ресурсов по Java, могутОбратите внимание на публичный аккаунт WeChat: Java3y.
Оглавление Навигация по статьям: