Как передать глобальные значения (синглтон против ???) - PullRequest
0 голосов
/ 18 сентября 2009

Я унаследовал проект, который хранит различные параметры в файле конфигурации, реестре и базе данных. Тот, кто нуждается в одном из этих параметров, просто читает (а в некоторых случаях пишет) его непосредственно из магазина. Это или, конечно, глупо, поэтому моей первой мыслью было реорганизовать существующий код, чтобы клиент не знал, где хранится параметр. Я создал классический класс AppSettings, у которого есть свойство для каждого параметра. Поскольку хранилище должно иметь глобальную область действия, я создал потокобезопасный синглтон. Класс не хранит значения параметров в полях, а действует как точка доступа, считывая и записывая их в фактическое хранилище, будь то файл конфигурации, реестр или база данных. В наши дни трудно избежать всех разговоров об опасностях синглетонов и глобального государства. Позже я расскажу о внедрении зависимостей, Spring и т. Д., Но сейчас у меня есть пара вопросов.

  1. Какие проблемы, кроме тестируемости, вы можете увидеть в моем решении?
  2. Какая альтернатива будет легче? Создание фабрики для каждого объекта, который использует параметры, не вариант (слишком много работы).
  3. Не будет ли использование синглтона приемлемым компромиссом, пока у меня не будет возможности провести более тяжелый рефакторинг?
  4. Если бы в свойствах моего синглтон-класса были только геттеры, это бы помогло?

Я могу предвидеть, что хранилище для некоторых параметров изменится в будущем (например, из реестра в базу данных), поэтому я и стал скрывать хранилище за синглтон-классом.

Ответы [ 3 ]

2 голосов
/ 18 сентября 2009

Это немного не отвечает, но я настоятельно рекомендую страницы c2wiki по Singletons в качестве ссылки http://c2.com/cgi/wiki?search=Singleton

А также страница http://c2.com/cgi/wiki?GlobalVariablesAreBad

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

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

0 голосов
/ 18 сентября 2009

Спасибо, ребята. Я бы посчитал, что это проект среднего размера (около 200KLOC), и это C #. Проблема в том, что у проекта долгая и проблемная история, и над ним работали многие программисты. Как бы я ни хотел правильно изучить внедрение зависимостей (насколько я понимаю и подписан на концепцию), крайний срок быстро закрывается, поэтому сейчас не время для этого. Посмотрев на мой текущий синглтон-класс, я решил разделить его на два экземпляра. Некоторые параметры используются повсеместно, но некоторые только в одной сборке. И, как сказал Дуг, я могу так же легко добиться безопасности потоков с помощью класса экземпляра.

Что касается различных структур внедрения зависимостей, проблема в том, что их слишком много. Я кратко посмотрел на Весну и Единство. Хотелось бы найти сводку различий.

Еще раз спасибо!

0 голосов
/ 18 сентября 2009

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

Если вам нужно писать потокобезопасным способом, вы можете создать статический (или одноэлементный) закрытый член класса AppSettings для управления только записью. Таким образом, любой экземпляр AppSettings может писать, но «глобальный» доступ фактически ограничен классом AppSettings.

...