Фабричный образец - Является ли наличие нескольких фабрик хорошей идеей? - PullRequest
2 голосов
/ 07 октября 2011

Я разрабатываю систему, которая позволяет пользователю назначать определенную задачу, которая будет выполняться при нажатии кнопки. Задача, которую нужно выполнить, может быть назначена на все виды вещей. Итак, у меня есть абстрактный базовый класс, называемый «ButtonTask», и все другие задачи наследуются от этой базы для реализации задачи, которую необходимо выполнить, вместе со связанными данными, которые нужно знать. Таким образом, я могу использовать полиморфизм для абстрагирования от всех особенностей, я просто вызываю «PerformTask», не заботясь о том, какой это тип на самом деле. Пока все хорошо.

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

На данный момент у меня есть фабричная функция, которая будет создавать правильный производный тип на основе сетевого сообщения и возвращать указатель на базовый тип. Проблема заключается в том, что меню пользовательского интерфейса и чтение файлов чувствуют, что им необходим собственный фабричный метод для создания объектов, поскольку они по своей сути отличаются друг от друга. Является ли вообще хорошей идеей иметь несколько фабрик для решения подобных проблем? Я не могу придумать другого пути решения этой проблемы, но, возможно, я могу сделать что-то более аккуратное.

1 Ответ

1 голос
/ 07 октября 2011

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

Если идея заключается в том, что задачи не зависят от того, как они были инициированы (GUI, сеть и т. д.), то я не вижу необходимости в отдельных фабричных методах.Вместо этого я бы сказал, что одной из обязанностей фабрики является достижение этой самой абстракции.Другими словами, вызывать одну и ту же фабрику из трех разных частей кода абсолютно нормально.Тем не менее, это хорошая идея сделать фабричный метод статичным или сделать фабрику одноэлементным объектом.

Если, с другой стороны, у вас есть ситуация, когда определенные задачи могут быть инициированы только из сети идругие из GUI, и только несколько могут быть инициированы всеми тремя способами, тогда, возможно, стоит немного переосмыслить дизайн.Затем вы должны рассмотреть возможность добавления другого уровня абстрактных классов Task, например CommonTask, GuiTask, NetworkTask, FileTask, и иметь фабрики для них вместо ButtonTask.Это, очевидно, более сложно, и стоит оно того или нет, зависит от количества классов задач и структуры вашего кода.

Чего вы хотите избежать, так это ситуации, когда пользователи фабрики знают, какие конкретныеПодклассы ButtonTask они могут получить с завода.Это ситуация «ложного базового класса», то есть ситуации, когда базовый класс не является истинной абстракцией всего набора его подклассов, и вы выходите из него, добавляя дополнительный слой подкласса, как описано выше.

Помимо этого, вы также можете рассмотреть возможность переименования ButtonTask;это звучит как задача только для графического интерфейса только из названия.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...