Singleton для чтения файла свойств в веб-приложении Java; правильный подход? - PullRequest
0 голосов
/ 22 декабря 2009

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

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

Изменить это:
accountLookupURL ="http://prodServer:8080/accountLookupService";

К этому:
accountLookupURL =urlLister.getURL("accountLookup");

Синглтон будет содержаться в списке URL.

Я склонен уклоняться от паттерна синглтона только потому, что раньше мне не приходилось его использовать. Я на правильном пути, здесь?

Спасибо!
IVR Avenger

Ответы [ 6 ]

3 голосов
/ 22 декабря 2009

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

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

2 голосов
/ 23 декабря 2009

В качестве альтернативы вы рассматривали возможность использования чего-то вроде Конфигурация Apache Commons (или, возможно, другой фреймворк конфигурации )?

1 голос
/ 23 декабря 2009

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

</p> <pre><code>public class WebServiceURLs { private static class WebServiceURLsHolder { public static WebServiceURLs webServiceURLs = new WebServiceURLs(); } private Properties webServiceURLs; public WebServiceURLs() { try { Properties newURLProperties = new Properties(); InputStreamReader inputStream = new InputStreamReader( FileLoader.class.getClassLoader().getResourceAsStream("../../config/URLs.properties") ); newURLProperties.load(inputStream); webServiceURLs =newURLProperties; } catch (Exception e) { webServiceURLs =null; } } public String getURLFromKey(String urlKey) { if (webServiceURLs==null) return null; else return webServiceURLs.getProperty(urlKey); } public static WebServiceURLs getInstance() { return WebServiceURLsHolder.webServiceURLs; } }

Это хорошее усилие как мой "первый" синглтон?

Спасибо
IVR Avenger

1 голос
/ 23 декабря 2009

Синглтоны подходят для этого сценария, НО вы должны убедиться, что вы делаете синглтон правильно.

Так, например, то, что предлагает Божно, - это не синглтон, это отвратительная смесь мерзкой статики, которая не является насмешливой, не легко проверяемой, не вводимой и обычно возвращается к вам в задницу.

Приемлемый синглтон - это просто ваш средний класс, за одним заметным исключением, что он гарантирован либо сам по себе, либо какой-либо внешней фабрикой / каркасом (например, Spring IoC) существовать только в одном экземпляре. Если вы идете с первым подходом, вы делаете что-то вроде

private MyUberSingletonClass() {
    //..do your constructor stuff, note it's private
}

private static MyUberSingletonClass instance = null;

public static synchronized MyUberSingletonClass instance() {
    if (instance == null) {
        instance = new MyUberSingletonClass();
    }
    return instance;
}

public String getUberUsefulStuff(){
    return "42";
}

Это приемлемо, если вы по-другому не чувствуете необходимость в фабрике и не используете какой-либо контейнер IoC в своем приложении (хотя стоит подумать об этом). Обратите внимание на отличие от примера Божно: это хороший класс vanilla, в котором единственным static является экземпляр var и метод для его возврата. Также обратите внимание на синхронизированное ключевое слово, необходимое для отложенной инициализации.

обновление: Паскаль рекомендует этот очень крутой пост о лучшем способе синглов с ленивым инициированием в комментариях ниже: http://crazybob.org/2007/01/lazy-loading-singletons.html

0 голосов
/ 22 декабря 2009

Синглтоны - это изменчивая статика и, следовательно, зло. (Предполагая достаточно полезное определение «синглтон».

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

В качестве примера, единственное, что останавливало последние версии JUnit 3, используемые в песочнице, это загрузка файла конфигурации в один статический инициализатор. Если бы он использовал параметризацию сверху, проблем бы не было.

0 голосов
/ 22 декабря 2009

Чтобы подтвердить очевидное, Singleton должен использоваться, когда весь клиентский код должен общаться с одним экземпляром класса. Итак, используйте Singleton IFF, вы уверены, что не хотите загружать несколько файлов свойств одновременно. Лично я хотел бы иметь возможность иметь эту функцию (загрузка нескольких файлов свойств).

...