Фабричный шаблон (или, по крайней мере, использование FactoryFactory..
) является предметом многих шуток, как здесь .
Помимо наличия подробных и «креативных» имен, таких как RequestProcessorFactoryFactory.RequestProcessorFactory , есть ли что-то принципиально неправильное в фабричном шаблоне, если вам нужно программировать на Java / C ++ и есть сценарий использования для Abstract_factory_pattern ?
Как другой популярный язык (например, Ruby или Scala ) мог бы избежать его использования при управлении аналогичной сложностью?
Причина, по которой я спрашиваю, состоит в том, что я вижу в основном критику фабрик, упомянутых в контексте экосистемы Java / Java EE , но они никогда не объясняют, как их решают другие языки / платформы.
java
design-patterns
senseiwu
источник
источник
Ответы:
Ваш вопрос помечен как «Java», поэтому неудивительно, что вы спрашиваете, почему шаблон фабрики высмеивается: сама Java поставляется с красиво упакованными нарушениями этого шаблона.
Например, попробуйте загрузить документ XML из файла и выполнить к нему запрос XPath. Вам нужно что-то вроде 10 строк кода, чтобы настроить фабрики и строителей:
Интересно, работали ли разработчики этого API когда-либо как разработчики или они просто читали книги и разбрасывали вещи? Я понимаю, что они просто не хотели писать синтаксический анализатор сами и оставили задачу другим, но это все равно делает уродливой реализацию.
Поскольку вы спрашиваете, что является альтернативой, здесь загружается файл XML в C #:
Я подозреваю, что новоявленные Java-разработчики видят безумие Фабрики и думают, что это нормально, если гении, создавшие Java, сами их использовали.
Фабричные и любые другие шаблоны - это инструменты, каждый из которых подходит для определенной работы. Если вы применяете их на рабочих местах, они не подходят, потому что у вас обязательно будет некрасивый код.
источник
XmlDocument xml = new XmlDocument(); xml.Load("c:\\employees.xml"); XmlNodeList nodes = xml.SelectNodes(expression);
(В целом, LINQ to XML гораздо проще в использовании, хотя в основном в других областях.) А вот статья KB Я нашел с помощью рекомендованного MS метода: support.microsoft.com/kb/308333Как это часто бывает, люди не понимают, что происходит (и это включает в себя многих смехотворцев).
Это не фабричный образец как таковой, как плохо, как многие (возможно, даже большинство) люди используют его.
И это, несомненно, проистекает из того, как программируется (и шаблоны). Школьникам (часто называющим себя «учениками») говорят «создать X, используя шаблон Y», и после нескольких итераций этого считают, что это подход к любой проблеме программирования.
Таким образом, они начинают применять определенный шаблон, который им нравится в школе, против всего и вся, будь то уместно или нет.
И это включает в себя университетских профессоров, которые печально пишут книги о разработке программного обеспечения.
Кульминацией этого стала система, которую я испытывал явное неудовольствие от необходимости поддерживать, и которая была создана одним из них (у этого человека даже было несколько книг об объектно-ориентированном дизайне, а также должность преподавателя на кафедре CS в крупном университете ).
Он был основан на трехуровневой схеме, причем каждый уровень сам по себе является трехуровневой системой (необходимо отделить ...). На интерфейсе между каждым набором уровней с обеих сторон была фабрика для создания объектов для передачи данных на другой уровень и фабрика для создания объекта для преобразования принятого объекта в один, принадлежащий принимающему уровню.
Для каждой фабрики была абстрактная фабрика (кто знает, фабрика, возможно, должна измениться, и тогда вы не хотите, чтобы вызывающий код изменился ...).
И весь этот беспорядок был, конечно, полностью без документов.
Система имела базу данных, нормализованную до 5-й нормальной формы (я не шучу).
Система, которая по сути была немногим больше, чем адресная книга, которую можно было использовать для регистрации и отслеживания входящих и исходящих документов, имела кодовую базу 100 МБ в C ++ и более 50 таблиц базы данных. Печать 500 бланков писем может занять до 72 часов с использованием принтера, подключенного напрямую к компьютеру, на котором запущено программное обеспечение.
Вот почему люди издеваются над шаблонами, и особенно люди, сосредоточенно сосредоточенные на одном конкретном шаблоне.
источник
Фабрики имеют много преимуществ, которые позволяют в некоторых ситуациях создавать элегантные проекты. Одним из них является то, что вы можете установить свойства объектов, которые вы позже хотите создать, в одном месте, создав фабрику, а затем передать эту фабрику. Но часто вам не нужно этого делать. В этом случае использование Factory просто добавляет дополнительную сложность, фактически не давая вам ничего взамен. Давайте возьмем эту фабрику, например:
Одной альтернативой шаблону Factory является очень похожий шаблон Builder. Основное отличие состоит в том, что свойства объектов, созданных Фабрикой, устанавливаются при инициализации Фабрики, тогда как Builder инициализируется с состоянием по умолчанию, а все свойства устанавливаются впоследствии.
Но когда ваша проблема заключается в переподготовке, замена Фабрики на Строителя, скорее всего, не является улучшением.
Самая простая замена для любого шаблона - это, конечно, создание экземпляров объекта с помощью простого конструктора с
new
оператором:Однако конструкторы имеют существенный недостаток в большинстве объектно-ориентированных языков: они должны возвращать объект именно этого класса и не могут возвращать подтип.
Когда вам нужно выбрать подтип во время выполнения, но вы не хотите создавать для этого целый новый класс Builder или Factory, вы можете использовать вместо этого метод factory. Это статический метод класса, который возвращает новые экземпляры этого класса или одного из его подклассов. Фабрика, которая не поддерживает никакого внутреннего состояния, часто может быть заменена таким фабричным методом:
Новая функция в Java 8 - ссылки на методы, которые позволяют передавать методы, как если бы вы работали с фабрикой без сохранения состояния. Удобно, что все, что принимает ссылку на метод, также принимает любой объект, который реализует тот же функциональный интерфейс, который также может быть полноценной фабрикой с внутренним состоянием, так что вы можете легко представить фабрики позже, когда увидите причину для этого.
источник
foo = new Bar(23);
будет эквивалентноfoo = Bar._createInstance(23);
. Объект должен иметь возможность надежно запрашивать свой собственный тип, используя закрытыйgetRealType()
метод, но объекты должны иметь возможность назначать супертип, который должен возвращаться при внешних вызовахgetType()
. Внешний код не должен заботиться о том,new String("A")
возвращает ли вызов на самом деле экземплярString
[в отличие, например, от экземпляраSingleCharacterString
].draw(OutputStream out)
но генерируют немного разные HTML, фабрика статических методов создает правильный класс для ситуации, и тогда вызывающая сторона может просто использовать метод draw.[[SomeClass alloc] init]
. Можно вернуть совершенно другой экземпляр класса или другой объект (например, кэшированное значение)Фабрики того или иного типа встречаются практически в любом объектно-ориентированном языке при соответствующих обстоятельствах. Иногда вам просто нужно выбрать способ создания объекта на основе простого параметра, например строки.
Некоторые люди заходят слишком далеко и пытаются спроектировать свой код, чтобы никогда не вызывать конструктор, кроме как внутри фабрики. Вещи начинают становиться смешными, когда у вас есть фабрики.
Что меня поразило, когда я выучил Scala, и я не знаю Ruby, но считаю, что это почти так же, так это то, что язык достаточно выразителен, так что программисты не всегда пытаются перенести «слесарную» работу во внешние файлы конфигурации , Вместо того, чтобы поддаваться искушению создать фабрики-фабрики для соединения ваших классов в различных конфигурациях, в Scala вы используете объекты со смешанными чертами. Кроме того, относительно просто создавать простые DSL на языке для задач, которые часто слишком перегружены в Java.
Кроме того, как отмечали другие комментарии и ответы, замыкания и функции первого класса устраняют необходимость во многих шаблонах. По этой причине я считаю, что многие антишаблоны начнут исчезать, поскольку C ++ 11 и Java 8 получат широкое распространение.
источник
В целом, существует такая тенденция, что Java-программы ужасно перегружены. Наличие многих фабрик является одним из наиболее распространенных симптомов чрезмерного проектирования; Вот почему люди смеются над этим.
В частности, проблема Java с фабриками заключается в том, что в Java а) конструкторы не являются функциями и б) функции не являются гражданами первого класса.
Представьте, что вы могли бы написать что-то вроде этого (пусть это
Function
будет хорошо известный интерфейс JRE )Видите, нет фабричных интерфейсов или классов. Многие динамические языки имеют первоклассные функции. Увы, это невозможно в Java 7 и более ранних версиях (реализация того же самого на фабриках оставлена читателю в качестве упражнения).
Таким образом, альтернатива заключается не столько в «использовании другого шаблона», сколько в «использовании языка с лучшей объектной моделью» или «не перегружать простыми задачами».
источник