> For the complete documentation index, see [llms.txt](https://itiu.gitbook.io/oop/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://itiu.gitbook.io/oop/patterns.-porozhdayushie.md).

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

Сreational patterns

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

![](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)
