На примере паттернов проектирования объясните различия между Factory Method, Abstract Factory и Strategy — приведите случаи, когда каждый из них наиболее уместен
Кратко и по делу — отличие, назначение, примеры и когда применять. Общее: - Factory Method и Abstract Factory — порождающие паттерны (решают проблему создания объектов). - Strategy — поведенческий паттерн (решает проблему выбора и смены алгоритма/поведения). Factory Method - Что делает: объявляет в базовом классе метод-фабрику, а подклассы переопределяют его, чтобы возвращать конкретный продукт. - Когда уместен: когда класс не знает заранее, какой конкретный подкласс должен быть создан, и когда вы хотите делегировать выбор подкласса наследникам. - Пример: базовый класс Document имеет метод createPage(), подклассы WordDocument, PdfDocument возвращают свои Page. Или GUI-элемент Creator создает Button, конкретные подклассы — WindowsCreator, LinuxCreator. - Плюсы: легко добавлять новые конкретные продукты, локализация знания о создании в подклассах. - Минусы: рост числа подклассов, логика создания распределена по иерархии. Abstract Factory - Что делает: предоставляет интерфейс для создания семейства взаимосвязанных или совместимых объектов (несколько видов продуктов) без указания их конкретных классов. - Когда уместен: когда нужно гарантировать, что создаваемые объекты из одной «семьи» совместимы друг с другом (темы UI, драйверы БД, наборы виджетов), и иметь возможность подменить всю семью объектов. - Пример: GUIFactory с методами createButton(), createCheckbox(); ConcreteFactoryWindows возвращает WindowsButton + WindowsCheckbox, ConcreteFactoryMac — MacButton + MacCheckbox. - Плюсы: обеспечивает согласованность семей объектов, упрощает смену реализации всей семьи. - Минусы: сложнее добавлять новые типы продуктов (нужно менять интерфейс фабрики и все реализации). Strategy - Что делает: инкапсулирует набор алгоритмов в отдельных классах и делает их взаимозаменяемыми; клиент держит ссылку на интерфейс стратегии и может менять поведение в рантайме. - Когда уместен: когда существует несколько алгоритмов решения одной задачи и нужно менять их динамически или тестировать/расширять без изменения клиента (например, способы сортировки, сжатия, расчёта налогов, валидации). - Пример: интерфейс CompressionStrategy с реализациями ZipStrategy, RarStrategy; объект Context (архиватор) использует выбранную стратегию. - Плюсы: упрощает добавление новых алгоритмов, делает код читаемым и тестируемым, поведение можно менять в рантайме. - Минусы: увеличивает число классов, клиент должен знать о стратегиях. Короткие правила выбора - Нужна ли вам гибкая смена алгоритма/поведения в рантайме? — выбирайте Strategy. - Нужна ли вам фабрика для одного продукта, но выбор конкретного подкласса должен выполняться подклассом/наследованием? — Factory Method. - Нужна ли вам фабрика, создающая целую согласованную «семью» разных объектов (и возможность менять всю семью сразу)? — Abstract Factory. Взаимосвязь - Abstract Factory часто реализуют через несколько Factory Methods внутри интерфейса фабрики. - Strategy и фабрики можно сочетать: фабрика создаёт нужную стратегию по конфигурации.
Общее:
- Factory Method и Abstract Factory — порождающие паттерны (решают проблему создания объектов).
- Strategy — поведенческий паттерн (решает проблему выбора и смены алгоритма/поведения).
Factory Method
- Что делает: объявляет в базовом классе метод-фабрику, а подклассы переопределяют его, чтобы возвращать конкретный продукт.
- Когда уместен: когда класс не знает заранее, какой конкретный подкласс должен быть создан, и когда вы хотите делегировать выбор подкласса наследникам.
- Пример: базовый класс Document имеет метод createPage(), подклассы WordDocument, PdfDocument возвращают свои Page. Или GUI-элемент Creator создает Button, конкретные подклассы — WindowsCreator, LinuxCreator.
- Плюсы: легко добавлять новые конкретные продукты, локализация знания о создании в подклассах.
- Минусы: рост числа подклассов, логика создания распределена по иерархии.
Abstract Factory
- Что делает: предоставляет интерфейс для создания семейства взаимосвязанных или совместимых объектов (несколько видов продуктов) без указания их конкретных классов.
- Когда уместен: когда нужно гарантировать, что создаваемые объекты из одной «семьи» совместимы друг с другом (темы UI, драйверы БД, наборы виджетов), и иметь возможность подменить всю семью объектов.
- Пример: GUIFactory с методами createButton(), createCheckbox(); ConcreteFactoryWindows возвращает WindowsButton + WindowsCheckbox, ConcreteFactoryMac — MacButton + MacCheckbox.
- Плюсы: обеспечивает согласованность семей объектов, упрощает смену реализации всей семьи.
- Минусы: сложнее добавлять новые типы продуктов (нужно менять интерфейс фабрики и все реализации).
Strategy
- Что делает: инкапсулирует набор алгоритмов в отдельных классах и делает их взаимозаменяемыми; клиент держит ссылку на интерфейс стратегии и может менять поведение в рантайме.
- Когда уместен: когда существует несколько алгоритмов решения одной задачи и нужно менять их динамически или тестировать/расширять без изменения клиента (например, способы сортировки, сжатия, расчёта налогов, валидации).
- Пример: интерфейс CompressionStrategy с реализациями ZipStrategy, RarStrategy; объект Context (архиватор) использует выбранную стратегию.
- Плюсы: упрощает добавление новых алгоритмов, делает код читаемым и тестируемым, поведение можно менять в рантайме.
- Минусы: увеличивает число классов, клиент должен знать о стратегиях.
Короткие правила выбора
- Нужна ли вам гибкая смена алгоритма/поведения в рантайме? — выбирайте Strategy.
- Нужна ли вам фабрика для одного продукта, но выбор конкретного подкласса должен выполняться подклассом/наследованием? — Factory Method.
- Нужна ли вам фабрика, создающая целую согласованную «семью» разных объектов (и возможность менять всю семью сразу)? — Abstract Factory.
Взаимосвязь
- Abstract Factory часто реализуют через несколько Factory Methods внутри интерфейса фабрики.
- Strategy и фабрики можно сочетать: фабрика создаёт нужную стратегию по конфигурации.