Сокрытие заводских реализаций - PullRequest
0 голосов
/ 30 августа 2018

В моем приложении я определил четыре интерфейса, скажем A, B, C и D. В зависимости от настроек времени компиляции, я бы хотел использовать разные реализации этих интерфейсов. Я определил абстрактную фабрику Factory примерно так:

package app.core;

abstract class Factory {
    public abstract A getA();
    public abstract B getB();
    public abstract C getC();
    public abstract D getD();
}

и две реализации, которые возвращают разные реализации интерфейсов A, B, C и D; каждый набор в другой упаковке:

package app.core.monolithic;

class MonoA implements A { ... } // and so on for B, C and D

class MonolithicFactory extends Factory {
    /* implementations of getters */
}

package app.core.modular;

class ModularA implements A { ... } // and so on for B, C and D

class ModularFactory extends Factory {
    /* implementations of getters */
}

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

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

1 Ответ

0 голосов
/ 30 августа 2018

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

Другой альтернативой является предоставление двух пакетов: API и JAR реализации.
Клиенты должны зависеть от jar-кода API во время компиляции и от JAR-файлов API и реализации во время выполнения.
Многие библиотеки работают таким образом, чтобы разделить внутренний API.

...