В чем разница между фабричным методом и астрактной фабрикой?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Разница между фабричным методом и абстрактной фабрикой
Оба паттерна решают проблему создания объектов, но на разных уровнях сложности. Это два из четырех основных паттернов создания объектов (Creational Patterns).
Factory Method (Фабричный метод)
Factory Method — это паттерн, который определяет интерфейс для создания объекта, но позволяет подклассам решать, какой класс инстанцировать.
Концепция:
Класс не создает объект напрямую (new Dog())
Вместо этого он вызывает метод create()
Метод решает, какой тип объекта создать
Характеристики:
- Создает ОДН ТИП объектов
- Инкапсулирует логику создания
- Позволяет подклассам переопределить тип
- Используется для одного семейства объектов
Пример в Dart:
abstract class Animal {
void makeSound();
// Фабричный метод
factory Animal.create(String type) {
switch (type) {
case 'dog':
return Dog();
case 'cat':
return Cat();
case 'bird':
return Bird();
default:
throw Exception('Неизвестный тип животного');
}
}
}
class Dog implements Animal {
@override
void makeSound() => print('Гав!');
}
class Cat implements Animal {
@override
void makeSound() => print('Мяу!');
}
class Bird implements Animal {
@override
void makeSound() => print('Чирик!');
}
// Использование
final dog = Animal.create('dog');
dog.makeSound(); // Гав!
final cat = Animal.create('cat');
cat.makeSound(); // Мяу!
Вариант с подклассом:
abstract class AnimalFactory {
Animal createAnimal();
}
class DogFactory extends AnimalFactory {
@override
Animal createAnimal() => Dog();
}
class CatFactory extends AnimalFactory {
@override
Animal createAnimal() => Cat();
}
// Использование
void animalDemo(AnimalFactory factory) {
final animal = factory.createAnimal();
animal.makeSound();
}
animalDemo(DogFactory()); // Гав!
animalDemo(CatFactory()); // Мяу!
Abstract Factory (Абстрактная фабрика)
Abstract Factory — это паттерн, который предоставляет интерфейс для создания СЕМЕЙСТВ связанных объектов без указания их конкретных классов.
Концепция:
Одна фабрика создает НЕСКОЛЬКО связанных объектов
Например:
- iOSFactory создает: iOSButton, iOSCheckbox, iOSTextField
- AndroidFactory создает: AndroidButton, AndroidCheckbox, AndroidTextField
Характеристики:
- Создает СЕМЕЙСТВА объектов
- Гарантирует совместимость между компонентами
- Используется когда нужно создать наборы связанных объектов
- Изолирует создание объектов
Пример в Dart:
// Интерфейсы для компонентов
abstract class Button {
void render();
}
abstract class CheckBox {
void render();
}
abstract class TextField {
void render();
}
// iOS компоненты
class IOSButton implements Button {
@override
void render() => print('iOS кнопка с скругленными углами');
}
class IOSCheckBox implements CheckBox {
@override
void render() => print('iOS чекбокс с iOS стилем');
}
class IOSTextField implements TextField {
@override
void render() => print('iOS текстовое поле');
}
// Android компоненты
class AndroidButton implements Button {
@override
void render() => print('Android Material кнопка');
}
class AndroidCheckBox implements CheckBox {
@override
void render() => print('Android Material чекбокс');
}
class AndroidTextField implements TextField {
@override
void render() => print('Android Material текстовое поле');
}
// Абстрактная фабрика
abstract class UIFactory {
Button createButton();
CheckBox createCheckBox();
TextField createTextField();
}
class IOSUIFactory implements UIFactory {
@override
Button createButton() => IOSButton();
@override
CheckBox createCheckBox() => IOSCheckBox();
@override
TextField createTextField() => IOSTextField();
}
class AndroidUIFactory implements UIFactory {
@override
Button createButton() => AndroidButton();
@override
CheckBox createCheckBox() => AndroidCheckBox();
@override
TextField createTextField() => AndroidTextField();
}
// Использование
class Application {
final UIFactory factory;
Application(this.factory);
void setupUI() {
final button = factory.createButton();
final checkbox = factory.createCheckBox();
final textfield = factory.createTextField();
button.render();
checkbox.render();
textfield.render();
}
}
// На iPhone
final app = Application(IOSUIFactory());
app.setupUI();
// iOS кнопка с скругленными углами
// iOS чекбокс с iOS стилем
// iOS текстовое поле
// На Android
final app = Application(AndroidUIFactory());
app.setupUI();
// Android Material кнопка
// Android Material чекбокс
// Android Material текстовое поле
Сравнительная таблица
Параметр | Factory Method | Abstract Factory
─────────────────┼──────────────────┼─────────────────
Что создает | Один объект | Семейство объектов
Уровень | Простой | Сложный
Количество | Одна иерархия | Несколько иерархий
иерархий | |
Использование | Вариации одного | Варианты целой
| продукта | системы
Сложность | Низкая | Высокая
Наследование | Один подкласс | Много подклассов
Примеры | HttpClient.create | ThemeFactory
| Logger.create | UIComponentsFactory
Примеры в Flutter
Factory Method: HTTP клиент
abstract class HttpClient {
Future<dynamic> get(String url);
Future<dynamic> post(String url, dynamic data);
factory HttpClient.create({String type = 'dio'}) {
switch (type) {
case 'dio':
return DioHttpClient();
case 'http':
return HttpHttpClient();
case 'mock':
return MockHttpClient();
default:
throw Exception('Unknown type');
}
}
}
// Использование
final client = HttpClient.create(type: 'dio');
const data = await client.get('https://api.example.com/users');
Abstract Factory: Темы оформления
abstract class ColorScheme {
Color get primaryColor;
Color get backgroundColor;
Color get textColor;
}
abstract class ButtonStyle {
double get borderRadius;
double get elevation;
}
abstract class Theme {
ColorScheme get colors;
ButtonStyle get buttonStyle;
}
// Light тема
class LightColorScheme implements ColorScheme {
@override
Color get primaryColor => Colors.blue;
@override
Color get backgroundColor => Colors.white;
@override
Color get textColor => Colors.black;
}
class LightButtonStyle implements ButtonStyle {
@override
double get borderRadius => 8;
@override
double get elevation => 2;
}
class LightTheme implements Theme {
@override
ColorScheme get colors => LightColorScheme();
@override
ButtonStyle get buttonStyle => LightButtonStyle();
}
// Dark тема
class DarkColorScheme implements ColorScheme {
@override
Color get primaryColor => Colors.deepOrange;
@override
Color get backgroundColor => Colors.grey[900]!;
@override
Color get textColor => Colors.white;
}
class DarkButtonStyle implements ButtonStyle {
@override
double get borderRadius => 12;
@override
double get elevation => 4;
}
class DarkTheme implements Theme {
@override
ColorScheme get colors => DarkColorScheme();
@override
ButtonStyle get buttonStyle => DarkButtonStyle();
}
// Использование
final isDarkMode = true;
final theme = isDarkMode ? DarkTheme() : LightTheme();
print(theme.colors.primaryColor); // Все компоненты темы согласованы!
print(theme.buttonStyle.borderRadius);
Когда использовать
Factory Method когда:
- Нужно создать один тип объектов
- Логика выбора простая
- Есть несколько вариантов одного класса
- Примеры: логирование, сериализация, кеш
Abstract Factory когда:
- Нужно создать семейства связанных объектов
- Хотите гарантировать совместимость компонентов
- Есть несколько полных наборов (темы, платформы, стили)
- Примеры: UI компоненты, темы, платформы
Вывод
Factory Method — это упрощенная версия создания объектов, когда нужно создавать один тип с разными вариантами.
Abstract Factory — это мощный паттерн для создания полных семейств объектов, которые должны работать вместе. Используйте его, когда нужна гарантия совместимости между группами связанных объектов.