Sobes.tech
Middle+
121
questionbank

Приведите примеры использования паттерна абстрактной фабрики.

Answer from AI

sobes.tech AI

Паттерн абстрактной фабрики полезен, когда требуется создать семейство связанных или зависимых объектов без указания их конкретных классов. Примеры из реальной практики:

  1. Создание элементов пользовательского интерфейса (GUI) для разных операционных систем:

    • Абстрактная фабрика (IGUIFactory) может иметь методы для создания кнопок (CreateButton), текстовых полей (CreateTextBox) и других элементов.
    • Конкретные фабрики (WindowsFactory, MacOSFactory) реализуют IGUIFactory, создавая элементы, специфичные для соответствующей платформы.
    • Клиентский код взаимодействует только с интерфейсами (IButton, ITextBox), не зная о конкретной реализации.
    // Абстрактные продукты
    public interface IButton
    {
        void Render();
    }
    
    public interface ITextBox
    {
        void ShowText();
    }
    
    // Конкретные продукты для Windows
    public class WindowsButton : IButton
    {
        public void Render() { /* Logic for rendering Windows button */ }
    }
    
    public class WindowsTextBox : ITextBox
    {
        public void ShowText() { /* Logic for showing text in Windows textbox */ }
    }
    
    // Конкретные продукты для MacOS
    public class MacOSButton : IButton
    {
        public void Render() { /* Logic for rendering MacOS button */ }
    }
    
    public class MacOSTextBox : ITextBox
    {
        public void ShowText() { /* Logic for showing text in MacOS textbox */ }
    }
    
    // Абстрактная фабрика
    public interface IGUIFactory
    {
        IButton CreateButton();
        ITextBox CreateTextBox();
    }
    
    // Конкретная фабрика для Windows
    public class WindowsFactory : IGUIFactory
    {
        public IButton CreateButton() { return new WindowsButton(); }
        public ITextBox CreateTextBox() { return new WindowsTextBox(); }
    }
    
    // Конкретная фабрика для MacOS
    public class MacOSFactory : IGUIFactory
    {
        public IButton CreateButton() { return new MacOSButton(); }
        public ITextBox CreateTextBox() { return new MacOSTextBox(); }
    }
    
    // Клиентский код
    public class Application
    {
        private readonly IGUIFactory _factory;
        private IButton _button;
        private ITextBox _textBox;
    
        public Application(IGUIFactory factory)
        {
            _factory = factory;
            _button = _factory.CreateButton();
            _textBox = _factory.CreateTextBox();
        }
    
        public void Paint()
        {
            _button.Render();
            _textBox.ShowText();
        }
    }
    
    // Использование
    // var factory = new WindowsFactory(); // Или new MacOSFactory();
    // var app = new Application(factory);
    // app.Paint();
    
  2. Создание объектов доступа к данным (DAO) для разных типов баз данных:

    • Абстрактная фабрика (IDatabaseFactory) может иметь методы для создания DAO для пользователей (CreateUserDAO), продуктов (CreateProductDAO) и т.д.
    • Конкретные фабрики (SqlDatabaseFactory, OracleDatabaseFactory) реализуют IDatabaseFactory, создавая DAO, специфичные для соответствующей БД.
    • Это позволяет легко поменять тип базы данных без изменения бизнес-логики.
    // Абстрактные DAO
    public interface IUserDAO
    {
        void InsertUser(string username);
    }
    
    public interface IProductDAO
    {
        void AddProduct(string productName);
    }
    
    // Конкретные DAO для SQL
    public class SqlUserDAO : IUserDAO
    {
        public void InsertUser(string username) { /* SQL INSERT logic */ }
    }
    
    public class SqlProductDAO : IProductDAO
    {
        public void AddProduct(string productName) { /* SQL INSERT logic */ }
    }
    
    // Конкретные DAO для Oracle
    public class OracleUserDAO : IUserDAO
    {
        public void InsertUser(string username) { /* Oracle INSERT logic */ }
    }
    
    public class OracleProductDAO : IProductDAO
    {
        public void AddProduct(string productName) { /* Oracle INSERT logic */ }
    }
    
    // Абстрактная фабрика
    public interface IDatabaseFactory
    {
        IUserDAO CreateUserDAO();
        IProductDAO CreateProductDAO();
    }
    
    // Конкретная фабрика для SQL
    public class SqlDatabaseFactory : IDatabaseFactory
    {
        public IUserDAO CreateUserDAO() { return new SqlUserDAO(); }
        public IProductDAO CreateProductDAO() { return new SqlProductDAO(); }
    }
    
    // Конкретная фабрика для Oracle
    public class OracleDatabaseFactory : IDatabaseFactory
    {
        public IUserDAO CreateUserDAO() { return new OracleUserDAO(); }
        public IProductDAO CreateProductDAO() { return new OracleProductDAO(); }
    }
    
    // Пример использования в бизнес-логике
    public class BusinessLogic
    {
        private readonly IDatabaseFactory _factory;
    
        public BusinessLogic(IDatabaseFactory factory)
        {
            _factory = factory;
        }
    
        public void RegisterUser(string username)
        {
            var userDAO = _factory.CreateUserDAO();
            userDAO.InsertUser(username);
        }
    }
    
  3. Создание объектов для работы с различными форматами файлов (пр. XML, JSON):

    • Абстрактная фабрика может создавать парсеры (CreateParser) и сериализаторы (CreateSerializer) для разных форматов.
    • Конкретные фабрики (XmlFactory, JsonFactory) будут предоставлять реализации, специфичные для XML и JSON.

Эти примеры демонстрируют, как абстрактная фабрика позволяет создавать семейства взаимосвязанных объектов, абстрагируя клиентский код от их конкретных реализаций и облегчая добавление новых вариантов семейств.