Створюючі шаблони проектування абстрагують процес створювання примірників. Вони допомагають зробити системно незалежним те як об'єкти створюються, компонуються і представляються. Шаблон створення класу використовує успадковування для того, щоб варіювати клас, примірник якого створюється, не дивлячись на те, що об'єкт створюючий шаблон буде делегувати створення примірника до іншого об'єкту. Створюючі шаблони стають важливими так як системи еволюціонують щоб залежати більш від об'єктної композиції, ніж від класового успадкування. Коли це трапляється, акцент змінюється від закодовування фіксованого набору поведінок до визначення меншого набору фундаментальних поведінок, які можуть бути скомпоновані до будь-якої кількості більш складних. Отак, створення об'єктів з певною поведінкою вимагає більше ніж просто створити примірник класу. Існують дві періодичні теми у цих шаблонах. По-перше, вони усі інкапсулюють знання про те які конкретні класи система використовує. По-друге, вони приховують те як примірники цих класів створюються і складаються разом. Уся система в загальному знає про об'єкти тільки те, які їхні інтерфейси - визначені абстрактними класами. Отже, створюючі шаблони дають вам велику гнучкість у тому, що створюється, хто це створює, як це створюється і коли. Вони дозволяють вам конфігурувати систему з об'єктами “продуктами”, які широко варіюються у структурі і функціональності. Конфігурація може бути статичною (тобто, вказаною під час компілювання) чи динамічною (під час виконання). Інколи створюючі шаблони являються конкурентами. Наприклад, існують випадки, коли обидва шаблони Прототип (Prototype) чи Абстрактна Фабрика (Absract Factory) можуть бути ефективно використаними. Іншим разом вони можуть компонувати співпрацювати один з одним: Будівник (Builder) може використовувати один з інших шаблонів для того, щоб реалізувати чиї компоненти повинні бути побудованими. Прототип (Prototype) може використовувати Синглтон (Singleton) у своїй реалізації. Через те, що створюючі шаблони сильно зв'язані, ми вивчимо усі п'ять з них разом, для того щоб висвітлити їхні подібності і відмінності. Ми також використаємо поширений приклад — побудову лабіринту для комп'ютерної гри, щоб проілюструвати їхню реалізацію. Лабіринт і гра будуть варіюватися від шаблону до шаблону. Інколи у грі буде просто знайти вихід з вашого лабіринту; у такому випадку гравець, можливо, буде мати його локальний вигляд. Інколи лабіринти будуть містити завдання для вирішення і небезпеки для їх переборення, і ці ігри можуть забезпечувати карту частин лабіринту, які були вже пройдені. Ми будемо ігнорувати багато деталей того, що може бути у лабіринті і чи підтримує гра одного чи декількох гравців. Замість того, ми просто сфокусуємось на тому, як лабіринти будуть створюватися. Ми визначимо лабіринт як набір кімнат. Кімната “знає” своїх сусідів; можливими сусідами є інші кімнати, стіна або двері в іншу кімнату. Класи Кімната, Двері і Стіна визначають компоненти лабіринту, які використовуються в усіх наших прикладах. Ми визначаємо частини цих класів, які є важливими для створення лабіринту. Ми будемо ігнорувати гравців, операції для відображення і кругового огляду у лабіринті, і інші важливі функції, які не відносяться до побудови лабіринту. Наступна діаграма показує відносини між цими класами: fig.3.fig1 Кожна кімната має чотири сторони. Ми використовуємо перечислення Direction у реалізації С++ для вказування півночі, півдня, сходу і заходу кімнати:
enum Direction {North, South, East, West} ;
Реалізація Smalltalk використовує відповідні символи для представлення цих напрямів. Клас MapSite являється загальним абстрактним класом для усіх компонентів лабіринту. Для спрощення прикладу, клас MapSite визначає тільки одну операцію — Enter. Її значення залежить від того у що ви входите. Якщо ви входите в кімнату, тоді змінюється ваше місце розташування. Якщо ви намагаєтесь увійти в двері, тоді відбуваються одна або дві речі: якщо двері відкриті, ви входите в наступну кімнату. Якщо двері закриті, тоді ви раните свій ніс.
сlass MapSie
{

  public:

    virtual void Enter() = 0 ;

} ;
Вхід забезпечує просту базу для більш розширених геометричних операцій. Наприклад, якщо ви є в кімнаті і говорите “Йди на Схід”, гра може просто миттєво визначити який клас MapSite є на схід і тоді викликати Enter з даного об'єкта. Специфічна для потомка операція Enter визначить чи змінилося ваше місце положення або ваш ніс буде боліти. У справжній грі, Enter може брати об'єкт гравця, що рухається як аргумент. Кімната являється конкретним класом-потомком класу MapSite, який визначає ключові відносини між компонентами у лабіринті. Він зберігає посилання до інших об'єктів MapSite і зберігає номер кімнати. Номер буде ідентифікувати кімнату у лабіринті.
class Room : public MapSite 
{ 

 public : 

    Room(int roomNo) ; 
    MapSite* GetSide(Direction) const ; 
    void SetSide(Direction, MapSite*) ; 
    virtual void Enter() ; 

 private: 

    MapSite* _sides[4] ; 
    int _roomNumber ; 

} ;
Наступні класи відображають стіну чи двері, які з'явился на кожній стороні кімнати.
class Wall : public MapSite 
{

 public: 

    Wall() ; 
    virtual void Enter() ; 

} ;

class Door : public MapSite 
{ 

 public : 

    Door(Room* = 0, Room* = 0) ; 
    virtual void Enter() ; 
    Room* OtherSideFrom(Room*) ; 

 private: 

    Room* _room1 ; 
    Room* _room2 ; 
    bool _isOpen ; 

} ;
Нам необхідно знати більше ніж просто про частини лабіринту. Ми також визначимо клас Maze (Лабіринт), який буде відображати колекцію кімнат. Магазин може також знайти певну кімнату, даючи номер кімнати до його перації RoomNo.
class Maze 
{ 

 public : 

    Maze() ; 
    void AddRoom(Room*) ; 
    Room* RoomNo(int) const ; 

 private: 

    // ... 

} ;
Операція RoomNo може робити пошук використовуючи лінійний пошук, хеш-таблицю, чи навіть простий масив. Але нам не потрібно хвилюватися тут про ці деталі. Замість того, ми зфокусуємсь на тому, як вказувати компоненти об'єкта лабіринту. Інший клас, який ми визначимо являється MazeGame, який створює лабіринт. Один прямолінійний шлях для створення лабіринту являється серії операцій, які додають компоненти до лабіринту і тоді зв'язують їх. Наприклад, наступний метод буде створювати лабіринт, який складається з двох кімнат з дверима між ними:
Maze* MazeGame :: CreateMaze ()
{ 
    Maze* aMaze = new Maze ; 
    Room* r1 = new Room(1) ; 
    Room* r2 = new Room(2) ; 
    Door* theDoor = new Door(r1, r2) ; 

    aMaze->AddRoom(r1) ; 
    aMaze->AddRoom(r2) ; 

    r1->SetSide(North, new Wall) ; 
    r1->SetSide(East, theDoor) ; 
    r1->SetSide(South, new Wall) ; 
    r1->SetSide(West, new Wall) ; 
    r2->SetSide(North, new Wall) ; 
    r2->SetSide(East, new Wall) ; 
    r2->SetSide(South, new Wall) ; 
    r2->SetSide(West, theDoor) ; 

    return aMaze ; 
}
Ця функція здається доволі складною, враховуючи те, що все що вона робить, це створює лабіринт з двома кімнатами. Існують очевидні шляхи зробити її простішою. Наприклад, конструктор класу Room може ініціалізовувати боки стінами. Але це просто переміщає код у інше місце. Реальна проблема цього методу не у його розмірі, а у його гнучкості. Вона жорстко закодовує план лабіринту. Зміна плану означає зміну цього методу, що означає повторну реалізацію або зміна його частин — що схильно до помилок і не сприяє повторному використанню. Створюючі шаблони показують як зробити цей дизайн більш гнучким, але не обов'язково меншим. В особливості, вони зроблять легшим зміну класів, які визначають компоненти лабіринту. Припустимо, що ви хочете повторно використати існуючий план лабіринту для нової гри, яка містить (з-поміж іншого) зачарований лабіринт. Зачарований лабіринт має новий тип компонентів на подобі DoorNeedingSpell, двері, які можуть відкритися тільки за допомогою закляття; і EnchantedRoom — кімната, яка може мати нетрадиційні лементи, на подобі ключів чи заклять. Як ви можете легко змінити CreateMaze так, щоб він створював лабіринти з цими новими класами об'єктів? У цьому випадку, найбільший бар'єр для зміни полягає у жорстко закодованих класах, що були створені. Створюючі шаблони забезпечують різні шляхи для видалення явних посилань до конкретних класів від коду, який потребує їхнього створення:
  • Якщо CreateMaze викликає віртуальну функцію замість того, щоб конструктор викликав методи для створення кімнат, стін і дверей, які йому потрібні, тоді ви зміните класи, примірники яких створюються, створюючи потомок класу MazeGame і перевизначаючи ці віртуальні функції. Цей підхід являється прикладом шаблону Метод Фабрики (Factory Method).
  • Якщо класу CreateMaze передають об'єкт як параметр для того щоб використати його для створення кімнат, стін і дверей, тоді ви можете змінити класи кімнат, стін і дверей передаючи різні параметри. Це є прикладом шаблону Абстрактної Фабрики (Abstract Factory).
  • Якщо класу CreateMaze передають об'єкт, який можу створювати новий лабіринт у його повноті використовуючи операції для додавання кімнат, дверей і стін до лабіринту, який він будує, тоді ви можете використати успадковування для зміни частин лабіринту або способу, яким він будується. Це є приклад шаблону Будівника (Builder).
  • Якщо клас CreateMaze параметризується декількома прототиповими об'єктами кімнати, дверей і стін, які він потім копіює і додає до лабіринту, тоді ви можете змінити композицію лабіринту, заміною цих прототипових об'єктів на інші. Це є прикладом шаблону Прототип (Prototype).
Останній створюючий шаблон, Синглтон (Singleton), може запевнити, що існує тільки один лабіринт на гру і що усі об'єкти ігор вже мають доступ до нього — без потрібності у глобальних об'єктах чи функціях. Синглтон також полегшує розширення чи заміну лабіринту без правки існуючого коду.