Как упаковать заводы в Java

Мне было интересно, как упаковать фабрики, которые у меня есть в моем приложении. Должен ли Factory быть в том же пакете, что и классы, которые его используют, в том же пакете, что и созданные им объекты, или в его собственном пакете?

Спасибо за ваше время и отзывы

Ответ 1

Обычно фабрики находятся в том же пакете, что и созданные ими объекты; ведь их целью является создание этих объектов. Обычно они не находятся в отдельном пакете (для этого нет причин). Кроме того, factory находится в том же пакете, что и созданные ими объекты, позволяет использовать видимость пакета.

Ответ 2

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

Например, представьте себе служебный поиск Factory, который совместно используется клиентской и серверной частью приложения, который возвращает клиентскую реализацию (которая находится в пакете только для клиента) на клиенте и на стороне сервера (в пакете только для сервера) при вызове из среды выполнения сервера.

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

Моя рекомендация:

  • Не добавляйте никаких ограничений на пакет классы имплантации, поскольку вы не знаю, какие реализации используемых в будущем, или в разных контексты.
  • Интерфейсы могут быть в одном и том же пакет, но это ограничение также ненужным и только делает конфигурация жесткая.
  • Конфигурируемые фабрики (например, поиск службы) могут быть повторно использованы и , если отображение интерфейса/реализации не является жестко запрограммированным. Только этот момент оправдывает наличие factory отделенные от обоих интерфейсов и классы реализации.

Ответ 3

Блок повторного использования является единицей выпуска. Это означает, что не должно быть связи между пакетами, поскольку упаковка, как правило, является самой низкой степенью детализации выпуска. Когда вы организовываете пакет, представьте себе, что вы говорите: "Здесь все, что вам нужно, чтобы использовать эти классы".

Ответ 4

Мне нравится помещать factory в пакет, для которого создаются объекты, именование здесь ключевое, если именование четкое и прозрачное, это поможет поддерживать усилия по линии.

Например, действие factory может быть структурировано как:

  • пакет org.program.actions
  • интерфейс org.program.actions.Action
  • enum org.program.actions.ActionTypes
  • factory org.program.actions.ActionFactory (или .ActionManager)
  • классы реализации org.program.actions.LogAction и т.д.

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

Ответ 5

Это полностью зависит от того, как вы собираетесь использовать указанные фабрики. Иногда имеет смысл разместить factory в своем собственном пакете.

У вас может быть, например, интерфейс, foo.bar.ui.Interface. Вы хотите иметь разные реализации этого интерфейса: один для AWT, один для Swing, один для консоли и т.д. Тогда было бы более целесообразно создать foo.bar.ui.swing.SwingInterfaceFactory, который создает foo.bar.ui.swing.SwingInterface. factory для foo.bar.ui.awt.AWTInterface будет тогда находиться в foo.bar.ui.awt.AWTInterfaceFactory.

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

Ответ 6

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

public interface Toy
{
    static class Factory
    {
        public static final Toy make() { ... }
    }
}

Toy toy = Toy.Factory.make();

ХА!

но make() не должен статически зависеть от подклассов Toy, это было бы плохо. он может выполнять некоторую динамическую магию, зависит от вашей стратегии factory.