Паттерны проектирования: Абстрактная фабрика (Abstract factory)

Абстрактная фабрика (Abstract factory) — порождающий шаблон проектирования, позволяющий изменять поведение системы, видоизменяя создаваемые объекты, но при этом не изменяя интерфейсы.

Задача:

Простейшая схема работы паттерна:

Хорошим примером демонстрации работы абстрактной фабрики является реализация поддержки различных графических интерфейсов в приложении. Примером для демонстрации будет являться DOS приложение, эмулирующее работу графического интерфейса. В программе будет 2 типа графического интерфейса: простой и дизайнерский (раскрашенный).

Для начала, создаём непосредственно интерфейс абстрактной фабрики, назовём его IGUIFactory:

 
	public interface IGUIFactory
    {
        IWindow Window();
        ILabel Label();
        IButton Button();
    }

В элемент окно можно вставлять множество кнопок и надписей. И у кнопки и надписи есть текст. Создадим интерфейс для элемента окна с названием IWindowElement:

 
	public interface IWindowElement
    {
        String Text { get; set; }
        void Print();
    }

Метод Print в нём, будет отвечать за отображение элемента на экране (в нашем случае, за вывод содержимого в консоль)

Теперь реализуем интерфейсы окна, кнопки и надписи:

 
public interface IWindow
    {
        String Name { get; set; }
        List ChildreElements { get;}
        void AddChild(IWindowElement child);
    }
public interface IButton : IWindowElement
    {
    }
public interface ILabel : IWindowElement
    {
    }

Теперь реализуем классы обычного и дизайнерского графического интерфейса. Фактически эти классы будут являться так называемой Concrete Factory.

Обычный графический интерфейс:

 
    public class StandartGUIFactory: IGUIFactory
    {
        public IWindow Window()
        {
           return new StandartWindow();
        }

        public ILabel Label()
        {
            return new StandartLabel();
        }

        public IButton Button()
        {
            return new StandartButton();
        }
    }

Дизайнерский графический интерфейс:

 
    public class DesignGUIFactory: IGUIFactory
    {
        public IWindow Window()
        {
            return new DesignWindow();
        }

        public ILabel Label()
        {
            return new DesignLabel();
        }

        public IButton Button()
        {
            return new DesignButton();
        }
    }

Класс дизайнерской кнопки будет выглядеть так:

 
	public class DesignButton: IButton
    {
        public DesignButton()
        {
            Text = "New Button";
        }
        public DesignButton(String text)
        {
            Text = text;
        }

        public string Text { get; set; }
        public void Print()
        {
            Console.WriteLine("<<<& {0} &>>>", Text);
        }
    }

Класс обычной кнопки:

 
    public class StandartButton : IButton
    {
        public StandartButton()
        {
            Text = "New Button";
        }
        public StandartButton(String text)
        {
            Text = text;
        }
        public string Text { get; set; }
        public void Print()
        {
            Console.WriteLine("<{0}>", Text);
        }
    }

Остальные элементы будут реализованы аналогичным образом. Все их можно посмотреть, скачав файлы данного проекта.

Тепер�� реализуем класс, работающий с данными графическими интерфейсами, я назвал его Client:

 
	public class Client
    {
        public void Print(IWindow window)
        {
            Console.WriteLine(window.Name);
            foreach (var child in window.ChildreElements)
            {
                child.Print();
            }
        }

        public IWindow CreateWindow(IGUIFactory guiFactoryfactory)
        {
            var window = guiFactoryfactory.Window();
            var button = guiFactoryfactory.Button();
            var label = guiFactoryfactory.Label();

            window.AddChild(button);
            window.AddChild(label);
            return window;
        }
    }

Осталось это всё протестировать:

 
    	var client = new Client.Client();

     	var standartWindow = client.CreateWindow(new StandartGUIFactory());
    	var designWindow = client.CreateWindow(new DesignGUIFactory());

    	client.Print(standartWindow);
     	client.Print(designWindow);

Результат работы:

 

Исходный код учебного проекта: https://github.com/flash2048/Patterns/tree/master/Factory

Добавить комментарий