# Шаблоны. Порождающие

## **Абстрактная фабрика**

![](https://habrastorage.org/getpro/habr/post_images/710/505/d1a/710505d1aff5667c97fcb06215faee31.jpg)

Сначала создадим абстрактную фабрику CarFactory, содержащую семейство из двух объектов — автомобиля и двигателя для него.

> &#x20; *abstract class CarFactory* \
> &#x20; *{* \
> &#x20;   *public abstract AbstractCar CreateCar();* \
> &#x20;   *public abstract AbstractEngine CreateEngine();* \
> &#x20; *}*

В результате у нас появился абстрактный класс с двумя методами, обеспечивающими получение соответствующих абстрактных объектов. Теперь реализуем первую конкретную фабрику, создающую класс, описывающий автомобиль BMW и двигатель для него:

> *class BMWFactory : CarFactory* \
> &#x20; *{* \
> &#x20;   *public override AbstractCar CreateCar()* \
> &#x20;   *{* \
> &#x20;     *return new BMWCar();* \
> &#x20;   *}* \
> *public override AbstractEngine CreateEngine()* \
> &#x20;   *{* \
> &#x20;    *return new BMWEngine();* \
> &#x20;   *}* \
> &#x20; *}*

Сделаем то же самое для автомобиля марки Audi, чтобы у нас возникла вторая конкретная фабрика:

> *class AudiFactory : CarFactory* \
> &#x20; *{* \
> &#x20;   *public override AbstractCar CreateCar()* \
> &#x20;   *{* \
> &#x20;    *return new AudiCar();* \
> &#x20;   *}*     \
> *public override AbstractEngine CreateEngine()* \
> &#x20;   *{* \
> &#x20;    *return new AudiEngine();* \
> &#x20;   *}* \
> &#x20; *}*

Теперь опишем абстрактный класс для наших автомобилей. В данном случае у них будет один метод, позволяющий узнать максимальную скорость машины. С его помощью мы обратимся и ко второму объекту — двигателю:

> &#x20;*abstract class AbstractCar* \
> &#x20;*{*    \
> &#x20; *public abstract void MaxSpeed(AbstractEngine engine);* \
> &#x20;*}*

Все двигатели, в свою очередь, будут содержать один параметр — максимальную скорость. Эта простая общедоступная переменная позволит сократить объем программы в данном примере:

> &#x20;*abstract class AbstractEngine* \
> &#x20; *{* \
> &#x20;    *public int max\_speed;* \
> &#x20; *}*

Реализуем класс для автомобиля BMW:

> &#x20;*class BMWCar : AbstractCar* \
> &#x20;*{* \
> *public override void MaxSpeed(AbstractEngine engine)* \
> *{* \
> *Console.WriteLine(«Макcимальная скорость: « + engine.max\_speed.ToString());* \
> *}* \
> &#x20;*}* <br>

А затем определяем параметры его двигателя:

> *class BMWEngine : AbstractEngine* \
> &#x20;*{*  \
> &#x20;  *public BMWEngine()* \
> &#x20;*{* \
> &#x20;   *max\_speed = 200;* \
> &#x20;*}* \
> &#x20;*}*

Проделаем то же самое для класса, описывающего автомобиль Audi:

> class AudiCar : AbstractCar \
> &#x20; *{* \
> *public override void MaxSpeed(AbstractEngine engine)* \
> *{* \
> *Console.WriteLine(«Макcимальная скорость: « + engine.max\_speed.ToString());* \
> *}* \
> *}*

Задаем двигатель для него: <br>

> *class AudiEngine : AbstractEngine* \
> &#x20; *{*   \
> &#x20; *public AudiEngine()* \
> &#x20; *{* \
> &#x20;   *max\_speed = 180;* \
> &#x20; *}* \
> &#x20; *}*

Теперь мы создадим класс Client, где покажем, как осуществляется работа с абстрактной фабрикой. В конструктор такого класса будут передаваться все конкретные фабрики, которые и начнут создавать объекты автомобиль и двигатель. Следовательно, в конструктор класса Client допустимо передать любую конкретную фабрику, работающую с любыми марками автомобилей. А метод Run позволит узнать максимальную скорость конкретной машины.

> &#x20;*class Client* \
> &#x20;*{* \
> &#x20;  *private AbstractCar abstractCar;* \
> *private AbstractEngine abstractEngine;*&#x20;
>
> \
> *public Client(CarFactory car\_factory)* \
> &#x20;  *{* \
> &#x20;    *abstractCar = car\_factory.CreateCar();* \
> &#x20;    *abstractEngine = car\_factory.CreateEngine ();* \
> &#x20;  *}*    \
> *public void Run()* \
> &#x20;  *{* \
> &#x20;     *abstractCar.MaxSpeed(abstractEngine);* \
> &#x20;   *}* \
> &#x20; *}*

Ниже показано, как вызвать метод Run с различными параметрами:

> &#x20;  *public static void Main()* \
> &#x20;  *{* \
> &#x20;    *// Абстрактная фабрика № 1* \
> &#x20;    *CarFactory bmw\_car = new BMWFactory ();* \
> &#x20;    *Client c1 = new Client(bmw\_car);* \
> &#x20;    *c1.Run();*     <br>
>
> &#x20;   *// Абстрактная фабрика № 2*      \
> &#x20;   *CarFactory audi\_factory = new AudiFactory();*      \
> &#x20;   *Client c2 = new Client(audi\_factory);*      \
> &#x20;    *c2.Run();* \
> &#x20;    *Console.Read();* \
> &#x20;   *}*

## **Строитель**

![](https://habrastorage.org/getpro/habr/post_images/16b/2fe/a7f/16b2fea7f7f4dcd14fe2ad0b0bb9bf84.jpg)

## **Фабричный метод**

![](https://habrastorage.org/getpro/habr/post_images/a79/c7d/d5e/a79c7dd5eaba210f19e194f2b97434d0.jpg)

## **Прототип**

![](https://habrastorage.org/getpro/habr/post_images/a9d/715/4a9/a9d7154a9b7e321a6330ab0c0337c061.jpg)

## **Одиночка**

![](https://habrastorage.org/getpro/habr/post_images/f80/871/aaf/f80871aaf46238adcc0cd2468f19a4c5.jpg)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://itiu.gitbook.io/oop/patterns.-porozhdayushie.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
