Из Википедии, бесплатной энциклопедии
  (Перенаправлено с абстрактной фабрики )
Перейти к навигации Перейти к поиску
Диаграмма классов UML

Абстрактная фабрика модель обеспечивает способ инкапсулировать группы отдельных заводов , которые имеют общую тему без указания их конкретных классов. [1] При обычном использовании клиентское программное обеспечение создает конкретную реализацию абстрактной фабрики, а затем использует общий интерфейс фабрики для создания конкретных объектов, которые являются частью темы. Клиент не знает (или уход) , какие конкретные объекты он получает от каждого из этих внутренних заводов, так как она использует только общие интерфейсы своих продуктов. [1]Этот шаблон отделяет детали реализации набора объектов от их общего использования и полагается на композицию объекта, поскольку создание объекта реализуется в методах, представленных в интерфейсе фабрики. [2]

Примером этого может быть абстрактный фабричный класс, DocumentCreatorкоторый предоставляет интерфейсы для создания ряда продуктов (например, createLetter()и createResume()). Система могла бы иметь любое количество производных конкретных версий DocumentCreatorкласса, таких как FancyDocumentCreatorили ModernDocumentCreator, каждая с другой реализацией, createLetter()и createResume()которые создавали бы соответствующий объект, например FancyLetterили ModernResume. Каждый из этих продуктов является производным от простого абстрактного класса , как Letterи Resumeиз которого клиент знает. Клиентский код будет получить соответствующий экземпляр из DocumentCreatorи вызывать его фабричные методы. Каждый из результирующих объектов будет создан на основе одной DocumentCreatorи той же реализации и будет иметь общую тему (все они будут модными или современными объектами). Клиенту нужно только знать, как обращаться с абстрактным Letterили Resumeклассом, а не с конкретной версией, полученной от конкретной фабрики.

Завод является расположение класса бетона в коде , на которых построены объекты . Цель использования шаблона - изолировать создание объектов от их использования и создать семейства связанных объектов без необходимости зависеть от их конкретных классов. [2] Это позволяет вводить новые производные типы без изменения кода, использующего базовый класс .

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

Обзор [ править ]

Шаблон проектирования Абстрактная фабрика [3] - один из двадцати трех хорошо известных шаблонов проектирования GoF, которые описывают, как решать повторяющиеся проблемы проектирования для разработки гибкого и многоразового объектно-ориентированного программного обеспечения, то есть объектов, которые легче реализовать, изменить , тестирование и повторное использование.

Шаблон проектирования «Абстрактная фабрика» решает такие проблемы, как: [4]

  • Как приложение может быть независимым от того, как создаются его объекты?
  • Как класс может быть независимым от того, как создаются требуемые ему объекты?
  • Как можно создать семейства связанных или зависимых объектов?

Создание объектов непосредственно внутри класса, которому требуются объекты, является негибким, потому что оно связывает класс с конкретными объектами и делает невозможным изменение экземпляра позже независимо от (без необходимости изменения) класса. Это предотвращает повторное использование класса, если требуются другие объекты, и затрудняет тестирование класса, поскольку реальные объекты не могут быть заменены фиктивными объектами.

Шаблон проектирования Абстрактная фабрика описывает, как решать такие проблемы:

  • Инкапсулируйте создание объекта в отдельный (фабричный) объект. То есть определите интерфейс (AbstractFactory) для создания объектов и реализуйте интерфейс.
  • Класс делегирует создание объекта объекту фабрики вместо того, чтобы создавать объекты напрямую.

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

Определение [ править ]

Суть шаблона абстрактной фабрики заключается в том, чтобы «предоставить интерфейс для создания семейств связанных или зависимых объектов без указания их конкретных классов». [5]

Использование [ править ]

Завод определяет фактический конкретный тип объекта должен быть создан, и именно здесь , что объект на самом деле создается (в C ++, например, с помощью нового оператора ). Однако фабрика возвращает только абстрактный указатель на созданный конкретный объект .

Это изолирует клиентский код от создания объекта , поскольку клиенты просят объект фабрики создать объект желаемого абстрактного типа и вернуть абстрактный указатель на объект. [6]

Поскольку фабрика возвращает только абстрактный указатель, клиентский код (который запросил объект у фабрики) не знает - и не обременен - ​​фактическим конкретным типом только что созданного объекта. Однако тип конкретного объекта (и, следовательно, конкретной фабрики) известен абстрактной фабрике; например, фабрика может прочитать его из файла конфигурации. Клиенту не нужно указывать тип, так как он уже указан в конфигурационном файле. В частности, это означает:

  • Клиентский код ничего не знает о конкретном типе , и ему не нужно включать какие-либо файлы заголовков или объявления классов, связанные с ним. Клиентский код имеет дело только с абстрактным типом. Объекты конкретного типа действительно создаются фабрикой, но клиентский код обращается к таким объектам только через их абстрактный интерфейс . [7]
  • Добавление новых конкретных типов выполняется путем изменения клиентского кода для использования другой фабрики, обычно это одна строка в одном файле. Затем другая фабрика создает объекты другого конкретного типа, но по-прежнему возвращает указатель того же абстрактного типа, что и раньше, тем самым изолируя клиентский код от изменений. Это значительно проще, чем изменение клиентского кода для создания экземпляра нового типа, что потребовало бы изменения каждого места в коде, где создается новый объект (а также обеспечения того, чтобы все такие места кода также знали о новом конкретном типе, путем включения, например, файла заголовка конкретного класса). Если все фабричные объекты хранятся глобально в синглтонеобъект, и весь клиентский код проходит через синглтон, чтобы получить доступ к надлежащей фабрике для создания объекта, тогда изменить фабрики так же просто, как изменить объект синглтона. [7]

Структура [ править ]

Диаграмма UML [ править ]

Класс пример Диаграмма Способ createButtonпо GUIFactoryвозвращений интерфейса объектов типа Button. Какая реализация Buttonбудет возвращена, зависит от того, какая реализация GUIFactoryобрабатывает вызов метода.
Пример класса UML и диаграммы последовательности для шаблона проектирования Абстрактная фабрика.[8]

В приведенной выше UML диаграммы классов , то Clientкласс , который требует ProductAи ProductBобъектов не создавать экземпляры ProductA1и ProductB1классов непосредственно. Вместо этого Clientотносится к AbstractFactoryинтерфейсу для создания объектов, который не Clientзависит от того, как создаются объекты (какие конкретные классы создаются). Factory1Класс реализует AbstractFactoryинтерфейс путем создания экземпляра ProductA1и ProductB1классов.
В UML диаграмма последовательности показывает время выполнения взаимодействия: В Clientобъектные вызовы createProductA()на Factory1объект, который создает и возвращает ProductA1объект. После этого Clientзвонки createProductB()наFactory1, который создает и возвращает ProductB1объект.

Диаграмма Lepus3 [ править ]

легенда

Пример Python [ править ]

from  abc  import  ABC ,  abstractmethod from  sys  import  platform Кнопка класса ( ABC ):  @abstractmethod  def  paint ( self ):  passclass  LinuxButton ( Button ):  def  paint ( self ):  return  «Визуализировать кнопку в стиле Linux»class  WindowsButton ( Button ):  def  paint ( self ):  return  «Визуализировать кнопку в стиле Windows»class  MacOSButton ( Button ):  def  paint ( self ):  return  «Визуализировать кнопку в стиле MacOS»класс  GUIFactory ( ABC ):  @abstractmethod  def  create_button ( self ):  passкласс  LinuxFactory ( GUIFactory ):  def  create_button ( self ):  return  LinuxButton ()класс  WindowsFactory ( GUIFactory ):  def  create_button ( self ):  return  WindowsButton ()класс  MacOSFactory ( GUIFactory ):  def  create_button ( self ):  return  MacOSButton ()if  platform  ==  "linux" :  factory  =  LinuxFactory () elif  platform  ==  "darwin" :  factory  =  MacOSFactory () elif  platform  ==  "win32" :  factory  =  WindowsFactory () else :  raise  NotImplementedError ( f "Не реализовано для вашей платформа: { платформа } " )кнопка  =  завод . create_button () результат  =  кнопка . краска () печать ( результат )

Альтернативная реализация с использованием самих классов как фабрик:

from  abc  import  ABC ,  abstractmethod from  sys  import  platform Кнопка класса ( ABC ):  @abstractmethod  def  paint ( self ):  passclass  LinuxButton ( Button ):  def  paint ( self ):  return  «Визуализировать кнопку в стиле Linux»class  WindowsButton ( Button ):  def  paint ( self ):  return  «Визуализировать кнопку в стиле Windows»class  MacOSButton ( Button ):  def  paint ( self ):  return  «Визуализировать кнопку в стиле MacOS»if  platform  ==  "linux" :  factory  =  LinuxButton elif  platform  ==  "darwin" :  factory  =  MacOSButton elif  platform  ==  "win32" :  factory  =  WindowsButton else :  raise  NotImplementedError ( f "Не реализовано для вашей платформы: { platform } " )button  =  factory () результат  =  кнопка . краска () печать ( результат )

См. Также [ править ]

  • Бетонный класс
  • Шаблон заводского метода
  • Создание объекта
  • Шаблон проектирования программного обеспечения

Ссылки [ править ]

  1. ^ a b Фриман, Эрик; Робсон, Элизабет; Сьерра, Кэти; Бейтс, Берт (2004). Хендриксон, Майк; Лукидес, Майк (ред.). Head First Design Patterns (мягкая обложка) . 1 . О'РЕЙЛИ. п. 156. ISBN. 978-0-596-00712-6. Проверено 12 сентября 2012 .
  2. ^ a b Фриман, Эрик; Робсон, Элизабет; Сьерра, Кэти; Бейтс, Берт (2004). Хендриксон, Майк; Лукидес, Майк (ред.). Head First Design Patterns (мягкая обложка) . 1 . О'РЕЙЛИ. п. 162. ISBN.  978-0-596-00712-6. Проверено 12 сентября 2012 .
  3. Эрих Гамма; Ричард Хелм; Ральф Джонсон; Джон Влиссидес (1994). Шаблоны проектирования: элементы объектно-ориентированного программного обеспечения многократного использования . Эддисон Уэсли. С.  87 и далее . ISBN 0-201-63361-2.
  4. ^ "Шаблон проектирования абстрактной фабрики - проблема, решение и применимость" . w3sDesign.com . Проверено 11 августа 2017 .
  5. ^ Гамма, Эрих; Ричард Хелм; Ральф Джонсон; Джон М. Влиссидес (2009-10-23). «Паттерны дизайна: абстрактная фабрика» . informIT. Архивировано из оригинала на 2009-10-23 . Проверено 16 мая 2012 . Создание объекта: Абстрактная фабрика: Цель: предоставить интерфейс для создания семейств связанных или зависимых объектов без указания их конкретных классов.
  6. ^ Veeneman, Дэвид (2009-10-23). «Объектный дизайн для недоумевших» . Кодовый проект. Архивировано из оригинала на 2011-09-18 . Проверено 16 мая 2012 . Фабрика изолирует клиента от изменений продукта или того, как он создается, и может обеспечить эту изоляцию между объектами, производными от самых разных абстрактных интерфейсов.
  7. ^ a b «Абстрактная фабрика: реализация» . OODesign.com . Проверено 16 мая 2012 .
  8. ^ "Шаблон проектирования абстрактной фабрики - структура и сотрудничество" . w3sDesign.com . Проверено 12 августа 2017 .

Внешние ссылки [ править ]

  • Реализация абстрактной фабрики на Java
  • СМИ, связанные с абстрактной фабрикой на Викискладе?
  • Абстрактная фабричная диаграмма UML + формальная спецификация в LePUS3 и Class-Z (язык описания дизайна)
  • Абстрактная фабрика Пример реализации абстрактной фабрики