Руководство по прохождению собеседования по Java (руководство по изучению Java, добро пожаловать в Star, будет продолжать улучшаться, приветствуются предложения и рекомендации):GitHub.com/snail Climb/…
Резюме истории:
Глубокое понимание шаблона singleton
Рекомендуемые исторические статьи:
Классическая базовая теория распределенных систем
Вероятно, самое красивое подробное объяснение управления транзакциями Spring.
Достаточно прочитать этот вопрос о виртуальной машине Java (jvm) в интервью
[TOC]
Знакомство с фабричным шаблоном
1.1 Определение фабричного шаблона
Давайте посмотрим на определение GOF для фабричного шаблона:
"Определите интерфейс для создания объекта, но позвольте подклассам решать, экземпляр какого класса создавать. Фабричный метод позволяет классу отложить создание экземпляра до подклассов" (Определите интерфейс для создания объекта в базовом классе, и пусть подклассы решат, какой класс создать экземпляр , Фабричные методы откладывают создание экземпляра класса до подклассов.)
1.2 Классификация фабричных моделей:
(1) Режим Simple Factory, также известный как Static Factory Method Pattern.
(2) режим фабричного метода, также известный как режим полиморфной фабрики или режим виртуального конструктора;
(3) Режим Abstract Factory (Абстрактная фабрика), также известный как режим Toolbox (Kit или Toolkit).
1.3 Использование в фреймворках с открытым исходным кодом
Приведу еще два распространенных примера (пока я могу точно их представить, конечно, их гораздо больше):
(1) Компоненты получаются через getBean("xxx") в Spring;
(2) В службе сообщений Java JMS (очередь сообщений ActiveMQ используется в качестве примера ниже)
Что касается использования очереди сообщений ActiveMQ, вы можете просмотреть:Подробное объяснение использования очереди сообщений ActiveMQ
// 1、创建一个连接工厂对象,需要指定服务的ip及端口。
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.25.155:61616");
// 2、使用工厂对象创建一个Connection对象。
Connection connection = connectionFactory.createConnection();
1.4 Зачем использовать заводской шаблон
(1) разъединение: разделить процесс создания объекта и использования
(2)Уменьшите дублирование кода:Если процесс создания объекта сложен, требует определенного количества кода и используется во многих местах, будет много повторяющегося кода.
(3) Сокращение затрат на техническое обслуживание: Поскольку процесс создания единообразно управляется фабрикой, то при изменении бизнес-логики нет необходимости находить все места, где нужно создать объект, чтобы исправлять его по одному, достаточно только модифицировать на фабрике для снижения затрат на техническое обслуживание.
О роли фабричного шаблона у Марка есть статья:blog.CSDN.net/love Lion/AR…
Две простые фабричные выкройки
2.1 Введение
Строго говоря, простой фабричный паттерн не является одним из 23 часто используемых шаблонов проектирования, это всего лишь специальная реализация фабричного паттерна. По сравнению с двумя другими фабричными шаблонами применение простого фабричного шаблона на практике относительно невелико, потому что он подходит только для многих простых ситуаций.
Самое главное, это противоречит тому, что мы сказали в обзорепринцип открыто-закрыто(Хотя этого можно избежать с помощью механизма отражения, который мы представим позже). Потому что каждый раз, когда вы хотите добавить новую функцию, вам нужно изменить код в необработанном операторе switch-case (или операторе if-else), чтобы добавить условия ветвления.
2.2 Применимые сценарии
(1) Необходимо создавать меньше объектов.
(2) Клиент не заботится о процессе создания объекта.
2.3 Назначение ролей в простом заводском шаблоне:
- Заводская роль: ядро шаблона Simple Factory, отвечающее за реализацию внутренней логики создания всех экземпляров. Фабричный класс может быть вызван непосредственно внешним миром для создания необходимых объектов продукта.
- Абстрактная роль продукта: родительский класс всех объектов, созданных по шаблону простой фабрики, который отвечает за описание общего интерфейса, общего для всех экземпляров.
- Конкретная роль продукта: цель создания простого фабричного шаблона, все созданные объекты являются экземплярами определенного класса, который играет эту роль.
2.4 Простой заводской пример
Создайте инструмент рисования, который может рисовать разные фигуры, вы можете рисовать круги, квадраты, треугольники, каждая фигура будет иметь метод draw() для рисования.
(1) Создайте интерфейс Shape
public interface Shape {
void draw();
}
(2) Создайте специальный графический класс, который реализует интерфейс
круглый
public class Circle implements Shape {
public Circle() {
System.out.println("Circle");
}
@Override
public void draw() {
System.out.println("Draw Circle");
}
}
Прямоугольник
public class Rectangle implements Shape {
public Rectangle() {
System.out.println("Rectangle");
}
@Override
public void draw() {
System.out.println("Draw Rectangle");
}
}
квадратный
public class Square implements Shape {
public Square() {
System.out.println("Square");
}
@Override
public void draw() {
System.out.println("Draw Square");
}
}
(3) Создайте класс factory:
public class ShapeFactory {
// 使用 getShape 方法获取形状类型的对象
public static Shape getShape(String shapeType) {
if (shapeType == null) {
return null;
}
if (shapeType.equalsIgnoreCase("CIRCLE")) {
return new Circle();
} else if (shapeType.equalsIgnoreCase("RECTANGLE")) {
return new Rectangle();
} else if (shapeType.equalsIgnoreCase("SQUARE")) {
return new Square();
}
return null;
}
}
(4) метод испытаний:
public class Test {
public static void main(String[] args) {
// 获取 Circle 的对象,并调用它的 draw 方法
Shape circle = ShapeFactory.getShape("CIRCLE");
circle.draw();
// 获取 Rectangle 的对象,并调用它的 draw 方法
Shape rectangle = ShapeFactory.getShape("RECTANGLE");
rectangle.draw();
// 获取 Square 的对象,并调用它的 draw 方法
Shape square = ShapeFactory.getShape("SQUARE");
square.draw();
}
}
Выходной результат:
Circle
Draw Circle
Rectangle
Draw Rectangle
Square
Draw Square
С этой реализацией есть проблема: если мы добавим новый класс продукта, нам нужно изменить метод getShape() в классе фабрики, что явно несовместимо спринцип открыто-закрыто.
2.5 Использование отражения для улучшения простых фабрик
Измените класс фабрики на следующую форму:
package factory_pattern;
/**
* 利用反射解决简单工厂每次增加新了产品类都要修改产品工厂的弊端
*
* @author Administrator
*
*/
public class ShapeFactory2 {
public static Object getClass(Class<? extends Shape> clazz) {
Object obj = null;
try {
obj = Class.forName(clazz.getName()).newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return obj;
}
}
Методы испытаний:
package factory_pattern;
public class Test2 {
public static void main(String[] args) {
Circle circle = (Circle) ShapeFactory2.getClass(factory_pattern.Circle.class);
circle.draw();
Rectangle rectangle = (Rectangle) ShapeFactory2.getClass(factory_pattern.Rectangle.class);
rectangle.draw();
Square square = (Square) ShapeFactory2.getClass(factory_pattern.Square.class);
square.draw();
}
}
Хотя этот метод соответствуетпринцип открыто-закрыто, но каждый раз передаются все пути класса продукта, что более проблематично. Если вам нужно улучшить, вы можете пройтиотражение + файл конфигурацииФорма для улучшения, этот метод также используется больше.
3 Шаблон фабричного метода
3.1 Введение
Модель фабричного метода должна быть самой модной в семействе фабричных моделей, и самой модной в общем проекте является именно эта мода.
Шаблон фабричного метода — это всего лишь один шаг вперед по сравнению с простой фабрикой.В шаблоне фабричного метода мы больше не предоставляем единый класс фабрики для создания всех объектов, а предоставляем разные фабрики для разных объектов. то естьКаждому объекту соответствует фабрика.
3.2 Применимые сценарии
- Класс не знает класс нужного ему объекта: в шаблоне метода фабрики клиенту не нужно знать имя класса конкретного класса продукта, а нужно знать только соответствующую фабрику, а конкретный объект продукта созданный конкретным фабричным классом; Клиент должен знать фабричный класс, который создает конкретный продукт.
- Класс указывает, какой объект создавать, через свой подкласс: в шаблоне фабричного метода для абстрактного фабричного класса необходимо предоставить только интерфейс для создания продукта, а его подкласс определяет конкретный создаваемый объект, используя объектно-ориентированный полиморфизм. Секс и Рихтер
- Делегируйте задачу создания объекта одному из нескольких подклассов фабрики. Клиент может использовать его, не заботясь о том, какой подкласс фабрики создает подкласс продукта, и динамически указывать его при необходимости. Можно указать имя класса конкретного класса фабрики. в файле конфигурации или базе данных.
3.3 Назначение роли шаблона фабричного метода:
- Роль абстрактной фабрики: является ядром шаблона фабричного метода и не имеет ничего общего с приложением. Любой фабричный класс для объектов, созданных в схеме, должен реализовывать этот интерфейс.
- Бетонный завод роль: это конкретный класс фабрики, который реализует интерфейс абстрактной фабрики, содержит логику, тесно связанную с приложением, и вызывается приложением для создания определенного типа объекта продукта.
- Абстрактная роль продукта: супертип объекта, созданный шаблоном фабричного метода, то есть общий родительский класс или интерфейс, принадлежащий объекту продукта.
- Конкретная роль продукта: эта роль реализует интерфейс, определенный абстрактной ролью продукта. Конкретный продукт создается конкретной конкретной фабрикой, и между ними часто существует взаимно однозначное соответствие.
3.4 Пример шаблона фабричного метода
Графический интерфейс и соответствующие классы реализации изображений в приведенном выше примере простой фабрики остаются без изменений. Нам просто нужно добавить фабричный интерфейс и фабричный класс, реализующий этот интерфейс.
(1) Добавьте заводской интерфейс:
public interface Factory {
public Shape getShape();
}
(2) Добавьте связанные фабричные классы:
круглый завод
public class CircleFactory implements Factory {
@Override
public Shape getShape() {
// TODO Auto-generated method stub
return new Circle();
}
}
Прямоугольный фабричный класс
public class RectangleFactory implements Factory{
@Override
public Shape getShape() {
// TODO Auto-generated method stub
return new Rectangle();
}
}
круглый завод
public class SquareFactory implements Factory{
@Override
public Shape getShape() {
// TODO Auto-generated method stub
return new Square();
}
}
(3) тест:
public class Test {
public static void main(String[] args) {
Factory circlefactory = new CircleFactory();
Shape circle = circlefactory.getShape();
circle.draw();
}
}
Выходной результат:
Circle
Draw Circle
4. Абстрактная фабрика
4.1 Введение
В паттерне фабричного метода у нас фактически есть подсознательное осознание. То есть мы производим однотипную продукцию. Шаблон абстрактной фабрики всего на один шаг дальше фабричного метода, в этом шаблоне класс фабрики может создавать не только один продукт, но и группу продуктов.
Абстрактная фабрика, пожалуй, самый сложный для понимания фабричный шаблон.
4.2 Применимые сценарии
- Как и в случае с фабричными методами, клиенту не нужно знать класс создаваемых им объектов.
- Когда группе объектов требуется выполнять определенную функцию вместе, могут быть ситуации, когда несколько групп объектов выполняют разные функции. (продукты, принадлежащие к одному семейству продуктов)
- Структура системы стабильна, и объекты не будут добавляться часто. (Поскольку после его добавления исходный код необходимо изменить, что не соответствует принципу открытого-закрытого)
4.3 Назначение роли шаблона абстрактного фабричного метода:
- Абстрактная фабрика (AbstractFactory) роль: является ядром шаблона фабричного метода и не имеет ничего общего с приложением. Любой фабричный класс для объектов, созданных в схеме, должен реализовывать этот интерфейс.
- Роль ConreteFactory: это конкретный класс фабрики, который реализует интерфейс абстрактной фабрики, содержит логику, тесно связанную с приложением, и вызывается приложением для создания определенного типа объекта продукта.
- Абстрактная роль продукта: супертип объекта, созданный шаблоном фабричного метода, то есть общий родительский класс или интерфейс, принадлежащий объекту продукта.
- Конкретная роль продукта: любой объект продукта, созданный шаблоном абстрактной фабрики, является экземпляром определенного класса продукта. Продукты, созданные на абстрактной фабрике, принадлежат к одному и тому же семейству продуктов, которое отличается от фабрики шаблоном фабрики, который создает только один продукт, который я подробно объясню позже.
.
4.4 В чем разница между фабрикой в абстрактной фабрике и фабрикой в фабричном методе?
Абстрактная фабрика должна производить весь набор продуктов (по крайней мере, два продукта), эти продукты должны быть связаны или зависеть друг от друга, а фабрика в фабричном методе - это фабрика, которая производит один продукт.
4.5 Экземпляры шаблона абстрактной фабрики
Я не знаю, играли ли вы в такие игры, как Cross Fire или Eating Chicken, в игре есть различные пушки. Мы предполагаем, что есть два типа оружия, АК и М4А1, каждому из которых соответствует пуля. Мы сейчас думаем, что завод, производящий АК, кстати, может выпускать пули для АК, а завод, который выпускает М4А1, кстати, может выпускать пули и для М4А1. (Завод АК производит продукцию серии АК, включая пули, типы автоматов АК, то же самое относится и к заводу M4A1)
(1) Создайте связанные интерфейсы:
пистолет
public interface Gun {
public void shooting();
}
пуля
public interface Bullet {
public void load();
}
(2) Создайте интерфейс, соответствующий классу реализации:
АК класс
public class AK implements Gun{
@Override
public void shooting() {
System.out.println("shooting with AK");
}
}
Класс М4А1
public class M4A1 implements Gun {
@Override
public void shooting() {
System.out.println("shooting with M4A1");
}
}
класс пули АК
public class AK_Bullet implements Bullet {
@Override
public void load() {
System.out.println("Load bullets with AK");
}
}
Класс пули M4A1
public class M4A1
_Bullet implements Bullet {
@Override
public void load() {
System.out.println("Load bullets with M4A1");
}
}
(3) Создать заводской интерфейс
public interface Factory {
public Gun produceGun();
public Bullet produceBullet();
}
(4) Создать конкретную фабрику
Завод по производству патронов АК и АК
public class AK_Factory implements Factory{
@Override
public Gun produceGun() {
return new AK();
}
@Override
public Bullet produceBullet() {
return new AK_Bullet();
}
}
Завод, производящий пули M4A1 и M4A1.
public class M4A1_Factory implements Factory{
@Override
public Gun produceGun() {
return new M4A1();
}
@Override
public Bullet produceBullet() {
return new M4A1_Bullet();
}
}
(5) Тест
public class Test {
public static void main(String[] args) {
Factory factory;
Gun gun;
Bullet bullet;
factory =new AK_Factory();
bullet=factory.produceBullet();
bullet.load();
gun=factory.produceGun();
gun.shooting();
}
}
Выходной результат:
Load bullets with AK
shooting with AK
Я Snailclimb, новичок, планирующий стать архитектором в ближайшие 5 лет. Добро пожаловать в мой публичный аккаунт WeChat: "Руководство по прохождению собеседования на Java"(Теплый общедоступный аккаунт WeChat, с нетерпением жду вместе с вами прогресса ~~~ настаивайте на оригинальности, делитесь красивыми текстами и делитесь различными учебными ресурсами Java)
Наконец, поработав некоторое время с сервером Alibaba Cloud, я понял, что Alibaba Cloud действительно хорош, поэтому подал заявку на пост представителя Alibaba Cloud.мой адрес купона.