Skip to content

Commit

Permalink
translation: Translate Abstract Factory to Russian / Fix #2286 partia…
Browse files Browse the repository at this point in the history
…lly (#2533)

* Translate Abstract Factory to Russian

* Fix a typo
  • Loading branch information
VladimirCreator authored Aug 20, 2023
1 parent 5f0da67 commit 376cd21
Showing 1 changed file with 237 additions and 0 deletions.
237 changes: 237 additions & 0 deletions localization/ru/abstract-factory/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
---
title: Abstract Factory
category: Creational
language: ru
tag:
- Gang of Four
---

## Альтернативные названия
Kit

## Цель
Предоставление интерфейса для создания семейств взаимосвязанных или взаимозависимых объектов без указания их конкретных классов.

## Объяснение
Пример из реального мира:
> Представьте, что вы хотите создать королевство с замком, королём и армией. Эльфийскому королевству понадобится эльфийский замок, эльфийский король и эльфийская армия, в то время как оркскому королевству понадобится оркский замок, оркский король и оркская армия. Между объектами королевства существует взаимозависимость.
Простыми словами:
> Фабрика фабрик; фабрика, которая объединяет отдельные, но взаимозависимые/взаимозаменяемые фабрики без указания их конкретных классов.
Википедия пишет:
> Порождающий шаблон проектирования, предоставляет интерфейс для создания семейств взаимосвязанных или взаимозависимых объектов, не специфицируя их конкретных классов.
**Программный пример**\
Основываясь на примере королевства выше, во-первых, нам понадобятся интерфейсы и реализации для объектов в королевстве.

```java
public interface Castle {
String getDescription();
}

public interface King {
String getDescription();
}

public interface Army {
String getDescription();
}

// Эльфийская реализация
public class ElfCastle implements Castle {
static final String DESCRIPTION = "Это эльфийский замок!";
@Override
public String getDescription() {
return DESCRIPTION;
}
}
public class ElfKing implements King {
static final String DESCRIPTION = "Это эльфийский король!";
@Override
public String getDescription() {
return DESCRIPTION;
}
}
public class ElfArmy implements Army {
static final String DESCRIPTION = "Это эльфийская армия!";
@Override
public String getDescription() {
return DESCRIPTION;
}
}

// Оркская реализация
public class OrcCastle implements Castle {
static final String DESCRIPTION = "Это оркский замок!";
@Override
public String getDescription() {
return DESCRIPTION;
}
}
public class OrcKing implements King {
static final String DESCRIPTION = "Это оркский король!";
@Override
public String getDescription() {
return DESCRIPTION;
}
}
public class OrcArmy implements Army {
static final String DESCRIPTION = "Это оркская армия!";
@Override
public String getDescription() {
return DESCRIPTION;
}
}
```

Во-вторых, нам понадобятся абстракция фабрики королевства, а также реализации этой абстракции:

```java
public interface KingdomFactory {
Castle createCastle();
King createKing();
Army createArmy();
}

public class ElfKingdomFactory implements KingdomFactory {

@Override
public Castle createCastle() {
return new ElfCastle();
}

@Override
public King createKing() {
return new ElfKing();
}

@Override
public Army createArmy() {
return new ElfArmy();
}
}

public class OrcKingdomFactory implements KingdomFactory {

@Override
public Castle createCastle() {
return new OrcCastle();
}

@Override
public King createKing() {
return new OrcKing();
}

@Override
public Army createArmy() {
return new OrcArmy();
}
}
```

На данный момент, у нас есть абстрактная фабрика, которая позволяет создавать семейство взаимосвязанных объектов, то есть фабрика эльфийского королевства создаёт эльфийский замок, эльфийского короля, эльфийскую армию и так далее:

```java
var factory = new ElfKingdomFactory();
var castle = factory.createCastle();
var king = factory.createKing();
var army = factory.createArmy();

castle.getDescription();
king.getDescription();
army.getDescription();
```

Вывод программы:

```
Это эльфийский замок!
Это эльфийский король!
Это эльфийская армия!
```

Можно спроектировать фабрику для наших различных фабрик королевств. В следующем примере, мы создали `FactoryMaker`, который ответственен за создание экземпляра `ElfKingdomFactory`, либо `OrcKingdomFactory`.

Клиент может использовать класс `FactoryMaker`, чтобы создать желаемую конкретную фабрику, которая в свою очередь будет производить разные конкретные объекты, унаследованные от `Castle`, `King`, `Army`.

В этом примере использовано перечисление, чтобы параметризовать то, какую фабрику королевства запрашивает клиент:

```java
public static class FactoryMaker {
public enum KingdomType {
ELF, ORC
}

public static KingdomFactory makeFactory(KingdomType type) {
return switch (type) {
case ELF -> new ElfKingdomFactory();
case ORC -> new OrcKingdomFactory();
default -> throe new IllegalArgumentException("Данный тип королества не поддерживается.")
}
}
}

public static void main(String[] args) {
var app = new App();

LOGGER.info("Эльфийское королевство");
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ELF));
LOGGER.indo(app.getCastle().getDescription());
LOGGER.indo(app.getKinv().getDescription());
LOGGER.indo(app.getArmy().getDescription());

LOGGER.info("Оркское королевство");

app.createKingdom(FactoryMaker.makeFactory(KingdomType.ORC));
LOGGER.indo(app.getCastle().getDescription());
LOGGER.indo(app.getKinv().getDescription());
LOGGER.indo(app.getArmy().getDescription());
}

```

## Диаграмма классов
![Диаграмма классов паттерна проектирования абстрактная фабрика](../../../abstract-factory/etc/abstract-factory.urm.png)

## Применимость
Используйте шаблон проектирования абстрактная фабрика, когда:

- Система должна быть независимой от того, как создаются, составляются и представляются её продукты;
- Система должна быть сконфигурирована одним из нескольких семейств продуктов;
- Семейство связанных продуктов спроектировано для совместного использования и вам необходимо обеспечить соблюдение данного ограничения;
- Вы хотите предоставить библиотеку классов, но готовы раскрыть только их интерфейсы, но не реализацию;
- Время жизни зависимости концептуально короче, чем время жизни потребителя;
- Вам требуется значение времени исполнения, чтобы создать требуемую зависимость;
- Вы хотите решить какие продукты из семейства вам нужны во время исполнения;
- Вам нужно предоставить один или несколько параметров, которые известны только во время исполнения прежде, чем вы сможете решить зависимость;
- В случае, когда требуется последовательность среди продуктов;
- Вы не хотите менять существующий код, когда добавляются новые продукты или семейство продуктов в программе.

Примеры сценариев использования:

- Выбор необходимой реализации FileSystemAcmeService или DataBaseAcmeSerivce или NetworkAcmeService во времени выполнения;
- Написание модульных тестов становится намного легче;
- Элементы графического пользовательского интерфейса для различных операционных систем.

## Следствия
- Внедрение зависимости в Java скрывает зависимости класса, приводящие к ошибкам времени выполнения, которые могли-бы быть обнаружены во времени компиляции;
- Данный паттерн проектирования отлично справляется с задачей создания уже определённых объектов, но добавление новых может быть трудоёмким;
- Код становится сложнее, чем ему следует из-за появления большого количества новых интерфейсов и классов, которые появляются вместе с этим паттерном проектирования.

## Руководства
* [Abstract Factory Pattern Tutorial](https://www.journaldev.com/1418/abstract-factory-design-pattern-in-java)

## Известные применения
* [javax.xml.parsers.DocumentBuilderFactory](http://docs.oracle.com/javase/8/docs/api/javax/xml/parsers/DocumentBuilderFactory.html)
* [javax.xml.transform.TransformerFactory](http://docs.oracle.com/javase/8/docs/api/javax/xml/transform/TransformerFactory.html#newInstance--)
* [javax.xml.xpath.XPathFactory](http://docs.oracle.com/javase/8/docs/api/javax/xml/xpath/XPathFactory.html#newInstance--)

## Родственные паттерны проектирования
* [Factory Method](https://java-design-patterns.com/patterns/factory-method/)
* [Factory Kit](https://java-design-patterns.com/patterns/factory-kit/)

## Благодарности
* [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)
* [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 comments on commit 376cd21

Please sign in to comment.