“Патерн Вівторка” #20: Абстракнта Фабрика (Abstract Factory)

Уявімо, що ви прийшли в іграшковий магазин (відіграючи роль діда мороза) і хочете накупляти іграшок дітям (не обов’язково своїм). Одна дитина любить плюшеві іграшки, вона часто із ними лягає у ліжко спати. А інша дитина страшна розбишака, ламає все на світі, рве м’які іграшки і зазвичай віддає перевагу гратися із твердими, дерев’яними іграшками. Двоє дітей хочуть ведмедика і котика і ще купу інших тваринок. На щастя магазин має широкий асортимент іграшок і ви вдосталь закупилися. В один мішок ви накидали дерев’яних іграшок, а в інший плюшевих.

Таким чином, коли ви підійшли до першої дитини, яка любить м’які іграшки, ви витягали із свого мішка спочатку плюшевого ведмедя, а далі плюшевого котика і так далі. Аналогічно ви підійшли до іншої дитини і подарували їй дерев’яного ведмедика і котика, і собаку і слона…

АБСТРАКТНА ФАБРИКА

Абстрактна фабрика – це дизайн патерн, що поставляє інтерфейс для створення сімейств об’єктів.

В нашому прикладі сімейством є іграшки із базовими класами Ведмедика (Bear), Кота (Cat). Абстрактною фабрикою є мішок. Одна із конкретних фабрик повертає дерев’яні іграшки, а інша повертає плюшеві. Тому якщо одна дитина просить котика то їй вернуть котика у відповідності до інстційованого мішка із ігрушками.

Я надіюся, що приклад із аналогіями видався гарним. Ну що подивимося трохи коду?

Абстрактна фабрика та конкретні реалізації (мішки)

Абстратна факбрики визначає інтерфейс, що повертає об’єкти Кота або Ведмедя (базові класи). Конкретні реалізації фабрики повертають конкретні реалізації ігрушок потрібного сімейства.

// abstract factory
// абстракна фабрика
public interface IToyFactory
{
Bear GetBear();
Cat GetCat();
}
// concrete factory
// конкретна фабрика
public class TeddyToysFactory : IToyFactory
{
public Bear GetBear()
{
return new TeddyBear();
}
public Cat GetCat()
{
return new TeddyCat();
}
}
// concrete factory
// конкретна фабрика
public class WoodenToysFactory : IToyFactory
{
public Bear GetBear()
{
return new WoodenBear();
}
public Cat GetCat()
{
return new WoodenCat();
}
}

Уже зрозуміло, що як тільки ми маємо якийсь екземпляр фабрики, ми можемо плодити сімейство потрібних іграшок. Тому глянемо на використання:

// lets start with wooden factory
// спочатку створимо дерев'яну фабрику
IToyFactory toyFactory = new WoodenToysFactory();

Bear bear = toyFactory.GetBear();
Cat cat = toyFactory.GetCat();
Console.WriteLine("I've got {0} and {1}", bear.Name, cat.Name);
// Output/Вивід: [I've got Wooden Bear and Wooden Cat]

/*--------------
somewhere else in the code...
десь далі в коді...
----------------*/

// and now teddy one
// а тепер плюшеву
IToyFactory toyFactory = new TeddyToysFactory();

Bear bear = toyFactory.GetBear();
Cat cat = toyFactory.GetCat();
Console.WriteLine("I've got {0} and {1}", bear.Name, cat.Name);
// Output/Вивід: [I've got Teddy Bear and Teddy Cat]

Два куски коду майже абсолютно ідентичні – різниця тільки в конктетному “мішку”.

Якщо вас ще цікавлять реалізації іграшок-тваринок, то вони доволі наївні.

public abstract class AnimalToy
{
protected AnimalToy(string name)
{
Name = name;
}
public string Name { get; private set; }
}
public abstract class Cat : AnimalToy
{
protected Cat(string name) : base(name) { }
}
public abstract class Bear : AnimalToy
{
protected Bear(string name) : base(name) { }
}
class WoodenCat : Cat
{
public WoodenCat() : base("Wooden Cat") { }
}
class TeddyCat : Cat
{
public TeddyCat() : base("Teddy Cat") { }
}
class WoodenBear : Bear
{
public WoodenBear() : base("Wooden Bear") { }
}
class TeddyBear : Bear
{
public TeddyBear() : base("Teddy Bear") { }
}

Абстрактна фабрика є дуже широковикористовуваним дизайн патерном. Дуже яскравим прикладом буде ADO.NET DbProviderFactory, яка є абстракною фабрикою, що визначає інтерфейси для отримання DbCommand, DbConnection, DbParameter і так далі. Конкретна фабрика SqlClientFactory поверне відповідно SqlCommand, SqlConnection і так далі.

Дякую за те що прочитали цей дизайн патерн із моїм прикладом (надіюся унікальним, якщо ні – то я перевинайшов колесо чи то що).

Моя табличка Патернів

Developer's RoadMap To Success

9 коментарів

Залишити коментар до Kalita Roman Скасувати коментар

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *