Skip to content

Commit 376cd21

Browse files
translation: Translate Abstract Factory to Russian / Fix #2286 partially (#2533)
* Translate Abstract Factory to Russian * Fix a typo
1 parent 5f0da67 commit 376cd21

File tree

1 file changed

+237
-0
lines changed

1 file changed

+237
-0
lines changed
Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
---
2+
title: Abstract Factory
3+
category: Creational
4+
language: ru
5+
tag:
6+
- Gang of Four
7+
---
8+
9+
## Альтернативные названия
10+
Kit
11+
12+
## Цель
13+
Предоставление интерфейса для создания семейств взаимосвязанных или взаимозависимых объектов без указания их конкретных классов.
14+
15+
## Объяснение
16+
Пример из реального мира:
17+
> Представьте, что вы хотите создать королевство с замком, королём и армией. Эльфийскому королевству понадобится эльфийский замок, эльфийский король и эльфийская армия, в то время как оркскому королевству понадобится оркский замок, оркский король и оркская армия. Между объектами королевства существует взаимозависимость.
18+
19+
Простыми словами:
20+
> Фабрика фабрик; фабрика, которая объединяет отдельные, но взаимозависимые/взаимозаменяемые фабрики без указания их конкретных классов.
21+
22+
Википедия пишет:
23+
> Порождающий шаблон проектирования, предоставляет интерфейс для создания семейств взаимосвязанных или взаимозависимых объектов, не специфицируя их конкретных классов.
24+
25+
**Программный пример**\
26+
Основываясь на примере королевства выше, во-первых, нам понадобятся интерфейсы и реализации для объектов в королевстве.
27+
28+
```java
29+
public interface Castle {
30+
String getDescription();
31+
}
32+
33+
public interface King {
34+
String getDescription();
35+
}
36+
37+
public interface Army {
38+
String getDescription();
39+
}
40+
41+
// Эльфийская реализация
42+
public class ElfCastle implements Castle {
43+
static final String DESCRIPTION = "Это эльфийский замок!";
44+
@Override
45+
public String getDescription() {
46+
return DESCRIPTION;
47+
}
48+
}
49+
public class ElfKing implements King {
50+
static final String DESCRIPTION = "Это эльфийский король!";
51+
@Override
52+
public String getDescription() {
53+
return DESCRIPTION;
54+
}
55+
}
56+
public class ElfArmy implements Army {
57+
static final String DESCRIPTION = "Это эльфийская армия!";
58+
@Override
59+
public String getDescription() {
60+
return DESCRIPTION;
61+
}
62+
}
63+
64+
// Оркская реализация
65+
public class OrcCastle implements Castle {
66+
static final String DESCRIPTION = "Это оркский замок!";
67+
@Override
68+
public String getDescription() {
69+
return DESCRIPTION;
70+
}
71+
}
72+
public class OrcKing implements King {
73+
static final String DESCRIPTION = "Это оркский король!";
74+
@Override
75+
public String getDescription() {
76+
return DESCRIPTION;
77+
}
78+
}
79+
public class OrcArmy implements Army {
80+
static final String DESCRIPTION = "Это оркская армия!";
81+
@Override
82+
public String getDescription() {
83+
return DESCRIPTION;
84+
}
85+
}
86+
```
87+
88+
Во-вторых, нам понадобятся абстракция фабрики королевства, а также реализации этой абстракции:
89+
90+
```java
91+
public interface KingdomFactory {
92+
Castle createCastle();
93+
King createKing();
94+
Army createArmy();
95+
}
96+
97+
public class ElfKingdomFactory implements KingdomFactory {
98+
99+
@Override
100+
public Castle createCastle() {
101+
return new ElfCastle();
102+
}
103+
104+
@Override
105+
public King createKing() {
106+
return new ElfKing();
107+
}
108+
109+
@Override
110+
public Army createArmy() {
111+
return new ElfArmy();
112+
}
113+
}
114+
115+
public class OrcKingdomFactory implements KingdomFactory {
116+
117+
@Override
118+
public Castle createCastle() {
119+
return new OrcCastle();
120+
}
121+
122+
@Override
123+
public King createKing() {
124+
return new OrcKing();
125+
}
126+
127+
@Override
128+
public Army createArmy() {
129+
return new OrcArmy();
130+
}
131+
}
132+
```
133+
134+
На данный момент, у нас есть абстрактная фабрика, которая позволяет создавать семейство взаимосвязанных объектов, то есть фабрика эльфийского королевства создаёт эльфийский замок, эльфийского короля, эльфийскую армию и так далее:
135+
136+
```java
137+
var factory = new ElfKingdomFactory();
138+
var castle = factory.createCastle();
139+
var king = factory.createKing();
140+
var army = factory.createArmy();
141+
142+
castle.getDescription();
143+
king.getDescription();
144+
army.getDescription();
145+
```
146+
147+
Вывод программы:
148+
149+
```
150+
Это эльфийский замок!
151+
Это эльфийский король!
152+
Это эльфийская армия!
153+
```
154+
155+
Можно спроектировать фабрику для наших различных фабрик королевств. В следующем примере, мы создали `FactoryMaker`, который ответственен за создание экземпляра `ElfKingdomFactory`, либо `OrcKingdomFactory`.
156+
157+
Клиент может использовать класс `FactoryMaker`, чтобы создать желаемую конкретную фабрику, которая в свою очередь будет производить разные конкретные объекты, унаследованные от `Castle`, `King`, `Army`.
158+
159+
В этом примере использовано перечисление, чтобы параметризовать то, какую фабрику королевства запрашивает клиент:
160+
161+
```java
162+
public static class FactoryMaker {
163+
public enum KingdomType {
164+
ELF, ORC
165+
}
166+
167+
public static KingdomFactory makeFactory(KingdomType type) {
168+
return switch (type) {
169+
case ELF -> new ElfKingdomFactory();
170+
case ORC -> new OrcKingdomFactory();
171+
default -> throe new IllegalArgumentException("Данный тип королества не поддерживается.")
172+
}
173+
}
174+
}
175+
176+
public static void main(String[] args) {
177+
var app = new App();
178+
179+
LOGGER.info("Эльфийское королевство");
180+
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ELF));
181+
LOGGER.indo(app.getCastle().getDescription());
182+
LOGGER.indo(app.getKinv().getDescription());
183+
LOGGER.indo(app.getArmy().getDescription());
184+
185+
LOGGER.info("Оркское королевство");
186+
187+
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ORC));
188+
LOGGER.indo(app.getCastle().getDescription());
189+
LOGGER.indo(app.getKinv().getDescription());
190+
LOGGER.indo(app.getArmy().getDescription());
191+
}
192+
193+
```
194+
195+
## Диаграмма классов
196+
![Диаграмма классов паттерна проектирования абстрактная фабрика](../../../abstract-factory/etc/abstract-factory.urm.png)
197+
198+
## Применимость
199+
Используйте шаблон проектирования абстрактная фабрика, когда:
200+
201+
- Система должна быть независимой от того, как создаются, составляются и представляются её продукты;
202+
- Система должна быть сконфигурирована одним из нескольких семейств продуктов;
203+
- Семейство связанных продуктов спроектировано для совместного использования и вам необходимо обеспечить соблюдение данного ограничения;
204+
- Вы хотите предоставить библиотеку классов, но готовы раскрыть только их интерфейсы, но не реализацию;
205+
- Время жизни зависимости концептуально короче, чем время жизни потребителя;
206+
- Вам требуется значение времени исполнения, чтобы создать требуемую зависимость;
207+
- Вы хотите решить какие продукты из семейства вам нужны во время исполнения;
208+
- Вам нужно предоставить один или несколько параметров, которые известны только во время исполнения прежде, чем вы сможете решить зависимость;
209+
- В случае, когда требуется последовательность среди продуктов;
210+
- Вы не хотите менять существующий код, когда добавляются новые продукты или семейство продуктов в программе.
211+
212+
Примеры сценариев использования:
213+
214+
- Выбор необходимой реализации FileSystemAcmeService или DataBaseAcmeSerivce или NetworkAcmeService во времени выполнения;
215+
- Написание модульных тестов становится намного легче;
216+
- Элементы графического пользовательского интерфейса для различных операционных систем.
217+
218+
## Следствия
219+
- Внедрение зависимости в Java скрывает зависимости класса, приводящие к ошибкам времени выполнения, которые могли-бы быть обнаружены во времени компиляции;
220+
- Данный паттерн проектирования отлично справляется с задачей создания уже определённых объектов, но добавление новых может быть трудоёмким;
221+
- Код становится сложнее, чем ему следует из-за появления большого количества новых интерфейсов и классов, которые появляются вместе с этим паттерном проектирования.
222+
223+
## Руководства
224+
* [Abstract Factory Pattern Tutorial](https://www.journaldev.com/1418/abstract-factory-design-pattern-in-java)
225+
226+
## Известные применения
227+
* [javax.xml.parsers.DocumentBuilderFactory](http://docs.oracle.com/javase/8/docs/api/javax/xml/parsers/DocumentBuilderFactory.html)
228+
* [javax.xml.transform.TransformerFactory](http://docs.oracle.com/javase/8/docs/api/javax/xml/transform/TransformerFactory.html#newInstance--)
229+
* [javax.xml.xpath.XPathFactory](http://docs.oracle.com/javase/8/docs/api/javax/xml/xpath/XPathFactory.html#newInstance--)
230+
231+
## Родственные паттерны проектирования
232+
* [Factory Method](https://java-design-patterns.com/patterns/factory-method/)
233+
* [Factory Kit](https://java-design-patterns.com/patterns/factory-kit/)
234+
235+
## Благодарности
236+
* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59)
237+
* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b)

0 commit comments

Comments
 (0)