smetaniny-react-generate-patterns
v1.0.2
Published
Generate Patterns
Downloads
11
Maintainers
Readme
Применение порождающих паттернов в React.js
В разработке крупных React-приложений часто возникает необходимость создавать гибкие и динамичные интерфейсы, управлять состоянием и конфигурациями компонентов. Порождающие паттерны проектирования, такие как Абстрактная фабрика, Фабричный метод, Строитель, Прототип и Синглтон, могут помочь решать эти задачи более эффективно, обеспечивая лучшее разделение ответственности, улучшение читаемости и поддерживаемости кода.
Библиотека реализована в рамках изучения порождающих паттернов
PHP Generate Patterns Example GitHub
1. Гибкая настройка компонентов
Применимость паттернов:
- Абстрактная фабрика — используется для создания коллекций компонентов, таких как формы для разных категорий пользователей или интерфейсных элементов (например, для мобильной и десктопной версий сайта).
- Фабричный метод — позволяет динамически создавать конкретные элементы интерфейса (кнопки, поля ввода, выпадающие списки), сохраняя общую логику построения интерфейса.
- Строитель — помогает пошагово создавать сложные формы или компоненты с большим количеством конфигураций (например, регистрационная форма для гостей и зарегистрированных пользователей).
- Прототип — позволяет быстро клонировать существующие компоненты или формы для повторного использования (например, дублирование карточек товаров или настроек формы).
- Синглтон — управляет состоянием приложения или хранением данных, таких как кэшированный контент или корзина покупок.
Пример:
В интернет-магазине можно использовать:
- Абстрактную фабрику для создания коллекций компонентов для админа и покупателей;
- Фабричный метод для генерации форм фильтрации товаров;
- Строитель для создания кастомных карточек товаров;
- Прототип для клонирования карточки товара;
- Синглтон для управления состоянием корзины покупок.
2. Создание и управление каталогом товаров
Применимость паттернов:
- Абстрактная фабрика — создаёт различные категории товаров (например, мужская и женская одежда), абстрагируясь от конкретных реализаций товаров.
- Фабричный метод — создаёт конкретные товары, например, костюмы, платья, рубашки.
- Строитель — используется для сборки сложных товаров, таких как костюмы, состоящие из нескольких частей (пиджак, брюки и жилет).
- Прототип — даёт возможность быстро клонировать товары для создания их вариаций (например, изменение цвета).
- Синглтон — управляет каталогом товаров, гарантируя единственный источник данных для всего приложения.
Пример:
Каталог интернет-магазина может использовать:
- Абстрактную фабрику для создания коллекций одежды;
- Фабричный метод для генерации конкретных товаров;
- Строитель для сборки кастомизированных товаров;
- Прототип для клонирования товаров для создания вариаций;
- Синглтон для управления состоянием каталога.
3. Создание динамических форм для разных пользователей
Применимость паттернов:
- Абстрактная фабрика — создаёт формы для разных типов пользователей (админ, редактор, пользователь).
- Фабричный метод — отвечает за создание отдельных полей формы, таких как текстовые поля, чекбоксы или радиокнопки.
- Строитель — позволяет динамически добавлять поля в зависимости от выбранных параметров (например, дополнительные поля для админа).
- Прототип — используется для клонирования стандартных форм и их последующей модификации.
- Синглтон — управляет глобальным состоянием форм, сохраняя данные между страницами.
Пример:
Форма для редактирования профиля может использовать:
- Абстрактную фабрику для создания различных форм в зависимости от типа пользователя;
- Фабричный метод для динамического добавления полей;
- Строитель для создания полей с зависимостями;
- Прототип для клонирования форм;
- Синглтон для сохранения данных формы между страницами.
4. Конфигурация интерфейса в административных панелях
Применимость паттернов:
- Абстрактная фабрика — создаёт различные страницы для управления контентом (пользователи, продукты, заказы).
- Фабричный метод — отвечает за создание конкретных элементов интерфейса, таких как таблицы, кнопки и фильтры.
- Строитель — позволяет динамически собирать страницы и виджеты с настраиваемыми фильтрами или таблицами.
- Прототип — помогает быстро дублировать существующие конфигурации страниц или виджетов.
- Синглтон — управляет глобальными настройками панели, такими как тема или разрешения пользователей.
Пример:
Админ-панель может использовать:
- Абстрактную фабрику для создания страниц управления пользователями и продуктами;
- Фабричный метод для добавления кнопок и таблиц;
- Строитель для создания сложных виджетов с несколькими фильтрами;
- Прототип для клонирования страниц;
- Синглтон для управления глобальными настройками панели.
5. Управление глобальными состояниями приложения
Применимость паттернов:
- Синглтон — широко используется для управления глобальными состояниями в React, такими как контексты (Context API) или состояния в библиотеке Redux.
Пример:
Синглтон может быть полезен при управлении такими глобальными состояниями, как:
- Темы оформления,
- Пользовательские настройки,
- Информация о сессии пользователя,
- Глобальные данные (например, о каталоге товаров).
6. Модульная сборка UI
Применимость паттернов:
- Фабричный метод — используется для создания элементов UI в зависимости от контекста и пропсов, что позволяет создавать модульные интерфейсы.
- Строитель — помогает создавать сложные UI-компоненты, такие как панели навигации с динамическим наполнением.
Пример:
В админ-панели можно динамически создавать элементы навигации в зависимости от прав пользователя:
- Фабричный метод генерирует кнопки и ссылки для каждого типа пользователя;
- Строитель формирует окончательную панель навигации с учётом всех элементов.
Заключение
Порождающие паттерны проектирования, такие как Абстрактная фабрика, Фабричный метод, Строитель, Прототип и Синглтон, позволяют создавать масштабируемые, поддерживаемые и гибкие React-приложения. Они помогают эффективно управлять созданием компонентов, состоянием и конфигурациями, что особенно важно в крупных проектах с динамическими интерфейсами.
| Критерий | Шаблон "Строитель" | Шаблон "Абстрактная Фабрика" | Шаблон "Фабричный метод" | Шаблон "Singleton" | Шаблон "Prototype" |
|-------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Описание | Позволяет поэтапно создавать сложные объекты. | Позволяет создавать семейства связанных объектов без указания их конкретных классов. | Делегирует создание объектов подклассам. | Гарантирует создание единственного экземпляра класса и предоставляет к нему глобальную точку доступа. | Позволяет копировать существующие объекты без зависимости от их классов. |
| Когда использовать | - Когда объект состоит из множества частей. - Когда необходимо создать разные представления одного и того же объекта. - Когда нужно повторное использование алгоритма построения. | - Когда необходимо создавать семейства связанных объектов. - Когда нужно избежать жесткой зависимости от конкретных классов. - Когда требуется совместимость между продуктами в семействе. | - Когда заранее неизвестно, какой именно объект необходимо создать. - Когда создание объектов является сложным процессом. - Когда нужно делегировать инстанцирование объектов. | - Когда нужен только один экземпляр класса. - Когда требуется контроль доступа к единственному экземпляру. | - Когда необходимо создать копию существующего объекта или несколько его вариаций. - Когда создание объекта трудоемкое или дорогостоящее. |
| Примеры применения | - Создание заказов, персонализация товаров, комплекты товаров. - Создание домов, автомобилей, интерфейсов с множеством настроек. | - Создание интерфейсов для различных семейств продуктов (например, одежда, обувь и аксессуары). | - Создание различных типов продуктов (одежда, электроника), способов доставки, методов оплаты. | - Менеджеры конфигурации, классы подключения к базам данных, файловым системам. - Логирование событий. | - Клонирование объектов, например, в системах управления прототипами продуктов. - Оптимизация производительности путем клонирования вместо создания с нуля. |
| Цель | Пошаговое создание сложных объектов с возможностью изменения представления. | Создание семейств связанных или зависимых объектов без указания их конкретных классов. | Делегирование создания объектов подклассам, позволяя изменять создаваемые объекты. | Обеспечение существования только одного экземпляра объекта, к которому можно получить доступ из любой точки программы. | Создание новых объектов на основе существующих, минимизируя зависимости от их классов. |
| Процесс | Процесс создания объекта разбивается на несколько шагов, которые управляются директором. | Клиентский код работает с интерфейсом, абстрактная фабрика создает конкретные продукты. Клиент не зависит от конкретных классов. | Создатель определяет фабричный метод, который возвращает объект нужного типа. Каждый подкласс создателя реализует свою логику. | Класс предоставляет метод для доступа к единственному экземпляру и гарантирует, что ни один другой экземпляр не будет создан. | Объект создает свои копии с использованием встроенного механизма клонирования (например, метод clone
в Java или __clone__
в PHP). |
| Возвращаемый объект | Сложный объект. | Семейство связанных объектов. | Конкретный продукт. | Единственный экземпляр объекта. | Копия существующего объекта. |
| Гибкость | Высокая, позволяет создавать различные представления одного и того же объекта. Позволяет изменять отдельные шаги построения. | Высокая, позволяет легко добавлять новые семейства продуктов. Однако добавление продуктов в существующие семейства может потребовать изменения интерфейсов. | Средняя, упрощает добавление новых типов продуктов, но требует создания новых подклассов для каждого типа. | Низкая, так как существует только один экземпляр объекта. | Высокая, так как позволяет клонировать объекты с различными настройками без зависимости от классов. |
| Структура объектов | Включает строителя, директора и продукт. | Включает интерфейсы для фабрики и конкретные классы продуктов. | Включает абстрактного создателя и конкретных создателей. | Включает класс с методом, который возвращает единственный экземпляр. | Включает интерфейс для клонирования и классы объектов, которые могут быть клонированы. |
| Сложность | Средняя, требует создания множества классов. | Высокая, требует больше абстракции и конфигурации. | Низкая, но может стать громоздкой с увеличением количества подклассов. | Низкая, но может усложняться реализация многопоточности или распределенных систем, где требуется гарантировать единственность экземпляра. | Низкая, но требует осторожности при клонировании сложных объектов, содержащих ссылки на другие объекты (глубокое и поверхностное копирование). |
| Недостатки | Множество классов для каждого конкретного случая, что может увеличивать сложность. | Может быть сложно добавить новые продукты в существующие семейства, если потребуется менять интерфейсы. | Для каждого нового типа продукта нужно создавать новый подкласс, что может усложнять поддержку проекта. | Может создавать проблемы с тестированием и расширением функционала. В многопоточных системах необходимо обеспечить корректное управление доступом к единственному экземпляру. | Может возникнуть необходимость в реализации глубокого копирования, что увеличивает сложность клонирования объектов с большим количеством зависимостей и связей. |
Описание
Чтобы сделать полный пример, включающий все порождающие паттерны (Абстрактная фабрика, Фабричный метод, Строитель, Прототип и Синглтон), мы расширим структуру проекта, добавив соответствующие паттерны. Структура будет построена таким образом, чтобы легко масштабироваться, добавлять новые категории одежды и новые типы продуктов, сохраняя при этом гибкость и модульность.
В данном проекте применяются следующие паттерны проектирования:
- Абстрактная фабрика: Позволяет создавать семейства связанных объектов (например, мужская и женская одежда) без указания их конкретных классов.
- Фабричный метод: Обеспечивает создание объектов, используя общие интерфейсы, что позволяет подменять реализацию в зависимости от контекста.
- Строитель: Упрощает создание сложных объектов (например, костюмов и платьев) поэтапно, обеспечивая гибкость в конфигурации.
- Прототип: Используется для клонирования объектов, что позволяет экономить ресурсы на создание новых экземпляров.
- Синглтон: Гарантирует, что класс имеет только один экземпляр (например, каталог продуктов) и предоставляет глобальную точку доступа к этому экземпляру.
Структура проекта
Проект включает следующие компоненты:
- Factories: Включает абстрактные фабрики для создания одежды (мужская, женская и костюмы).
- Builders: Определяет строителей для создания различных компонентов одежды (костюмы и платья).
- Products: Содержит интерфейсы и классы для различных типов одежды (костюмы, платья, сложные предметы одежды).
- Prototypes: Определяет прототипы для клонирования объектов одежды и реестр для управления прототипами.
- Singletons: Определяет синглтон для управления доступом к каталогу продуктов.
- GeneratePatternsController: Управляет процессом создания одежды и отображения информации о продуктах.
- ProductCatalogContext: Контекст для управления состоянием каталога продуктов в приложении.
/GeneratePatterns
│
├── /Factories/ # Папка с фабриками и абстрактными фабриками
│ ├── AbstractClothingFactory.ts # Абстрактная фабрика для одежды
│ ├── MenClothingFactory.ts # Фабрика для мужской одежды
│ ├── WomenClothingFactory.ts # Фабрика для женской одежды
│ ├── SuitFactory.ts # Фабричный метод для создания костюмов
│
├── /Builders/ # Папка с паттернами Строитель
│ ├── SuitBuilder.ts # Строитель для костюмов
│ └── DressBuilder.ts # Строитель для платьев
│
├── /Products/ # Конкретные классы одежды (объекты)
│ ├── Suit.ts # Класс костюма
│ ├── Dress.ts # Класс платья
│ ├── CustomSuit.ts # Класс костюма, созданного через Строитель
│ └── Contracts/ # Интерфейсы для объектов
│ ├── ClothingItem.ts # Интерфейс для одежды
│ └── ComplexClothingItem.ts # Интерфейс для сложных объектов одежды
│
├── /Prototypes/ # Паттерн Прототип для клонирования объектов
│ ├── ClothingPrototype.ts # Абстрактный класс прототипа
│ ├── SuitPrototype.ts # Прототип для костюмов
│ ├── DressPrototype.ts # Прототип для платьев
│ └── PrototypeRegistry.ts # Реестр прототипов для быстрого клонирования
│
├── /Singletons/ # Паттерн Синглтон
│ └── ProductCatalogSingleton.ts # Синглтон для каталога продуктов
│
└── GeneratePatternsController.ts # Пример использования всех паттернов
import React, {useState, useEffect} from "react";
import {
ClothingItem,
ComplexClothingItem,
ProductCatalogSingleton,
SuitBuilder,
WomenClothingFactory,
} from "react-generate-patterns";
const GeneratePatterns: React.FC = () => {
// Состояние для хранения списка продуктов в каталоге
const [catalogProducts, setCatalogProducts] = useState < ClothingItem[] > ([]);
useEffect(() => {
// Получаем экземпляр синглтона для управления каталогом продуктов
const catalog = ProductCatalogSingleton.getInstance();
const builder = new SuitBuilder();
// Очищаем каталог перед каждым добавлением новых продуктов
catalog.clearCatalog();
// 1. Создаем мужской костюм (пиджак, брюки, жилет)
builder.createJacket(); // Добавляем пиджак
builder.createTrousers(); // Добавляем брюки
builder.createVest(); // Добавляем жилет
const menSuitPrototype = new SuitPrototype(builder.getResult()); // Прототип мужского костюма
catalog.addProduct(menSuitPrototype.clone()); // Добавляем клонированный костюм
builder.reset(); // Сбрасываем билдер
// 2. Создаем женский костюм с брюками и жилетом
builder.createTrousers();
builder.createVest();
const womenComplexSuit = builder.getResult();
catalog.addProduct(womenComplexSuit);
builder.reset(); // Сбрасываем билдер
// 3. Добавляем женское платье через прототип
const womenDressPrototype = new DressPrototype(new WomenClothingFactory().createClothingItem());
catalog.addProduct(womenDressPrototype.clone());
// 4. Создаем мужской костюм только с брюками
builder.createTrousers();
const trousersOnlySuit = builder.getResult();
catalog.addProduct(trousersOnlySuit);
builder.reset(); // Сбрасываем билдер
// 5. Создаем женский костюм только с жилетом
builder.createVest();
const vestOnlySuit = builder.getResult();
catalog.addProduct(vestOnlySuit);
builder.reset(); // Сбрасываем билдер
// 6. Создаем полный комплект костюма (пиджак, брюки, жилет)
builder.createJacket();
builder.createTrousers();
builder.createVest();
const fullSuit = builder.getResult();
catalog.addProduct(fullSuit);
builder.reset(); // Сбрасываем билдер
// Обновляем состояние с продуктами из каталога
setCatalogProducts(catalog.getProducts());
}, []);
return (
<div>
<h1>Каталог Продуктов</h1>
<ul>
{catalogProducts.map((item, index) => (
<li key={index} style={{marginBottom: "20px"}}>
<p>
<strong>{item.getDescription()}</strong>
- {item.getPrice()} руб.
</p>
{/* Проверяем, есть ли компоненты у товара */}
{"getComponents" in item && (
<ul>
<i>Составляющие костюма:</i>
{(item as ComplexClothingItem).getComponents().map((component: string, compIndex: number) => (
<li key={compIndex}>{component}</li>
))}
</ul>
)}
</li>
))}
</ul>
</div>
);
};
export default GeneratePatterns;