Java - предотвращение расщепления многоязычной версии кода - PullRequest
2 голосов
/ 20 мая 2009

Я пишу приложение, которое будет поставляться в нескольких разных версиях (изначально будет существовать около 10 вариантов кодовой базы, и их необходимо будет поддерживать). Конечно, 98% или около того кода будет одинаковым для разных систем, и имеет смысл сохранить базу кода без изменений.

Мой вопрос - какой способ сделать это предпочтительнее? Если у меня, например, есть класс (MyClass), который отличается в некоторых версиях (MyClassDifferent), и на этот класс ссылаются в нескольких местах. Я хотел бы, чтобы эта ссылка изменилась в зависимости от того, какую версию приложения я компилирую, вместо того, чтобы разбивать все классы, ссылающиеся на MyClassDifferent. Макросы препроцессора были бы хороши, но они раздувают код, и на самом деле есть только доказательства реализации концепций?

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

Ответы [ 4 ]

4 голосов
/ 20 мая 2009

Вы на правильном пути: заводские шаблоны, конфигурация и т. Д.

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

2 голосов
/ 20 мая 2009

к счастью, у вас есть несколько вариантов

1) ServiceLoader (встроенный в java6) поместите ваш класс API, такой как MyClass, в jar, скомпилируйте ваше приложение с этим API. Затем поместите отдельную реализацию MyClass в отдельный jar с /META-INF/services/com.foo.MyClass. , Затем вы можете поддерживать несколько версий вашего приложения, просто сохраняя «раздачу» jar-файлов. Ваш "основной" класс - это просто набор вызовов ServiceLoader

2) та же архитектура 1), но замена служб META-INF на конфигурацию Spring или Guice

3) ОСГИ

4) ваше решение

2 голосов
/ 20 мая 2009

Я бы поддержал ваш заводской подход, и вы должны ближе познакомиться с maven или ant (в зависимости от того, что вы используете). Вы можете развернуть различные файлы конфигурации, которые определяют, какие классы используются на основе параметров / профилей.

Препроцессорные макросы, такие как C / C ++, не доступны напрямую для Java. Хотя возможно это можно эмулировать с помощью скриптов сборки. Но я бы не пошел по этому пути. Мое предложение - придерживаться заводского подхода.

1 голос
/ 22 мая 2009

Найдите шаблон проектирования AbstractFactory, «Внедрение зависимостей» и «Инверсия управления». Мартин Фаулер пишет об этих здесь .

Вкратце, вы отправляете файлы JAR со всеми необходимыми компонентами. Для каждой точки обслуживания, которую можно настроить, вы определяете интерфейс для службы. Затем вы пишете одну или несколько реализаций этого интерфейса. Чтобы создать сервисный объект, вы запрашиваете у него AbstractFactory, например:

AbstractFactory factory = new AbstractFactory();
...
ServiceXYZ s = factory.newServiceXYZ();
s.doThis();
s.doThat();

Внутри AbstractFactory вы создаете соответствующий объект ServiceXYZ, используя Java-метод отражения Class.classForName () и SomeClassObject.newInstance (). (Выполнение этого означает, что вам не нужно иметь класс ServiceXYZ в файлах jar, если это не имеет смысла. Вы также можете создавать объекты в обычном режиме.)

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

Вы можете достаточно легко развернуть собственное решение или использовать такие рамки, как Spring , Guice или Pico .

...