У меня есть класс Config, который управляет конфигурацией приложения, настройками и т. д. Я хочу, чтобы другие классы могли его использовать, но передавать его каждому методу в качестве ссылки - боль, и у меня есть ощущение, что есть лучший способ сделать это.
так что это мой заголовок класса конфигурации:
class Config
{
public:
Config();
public:
char *port;
template <class Type = std::string>
Type get(std::string value)
{
return _config.get<Type>(value);
};
void set(std::string key,std::string value){
_config.put(key,value);
boost::property_tree::json_parser::write_json("config.json",_config);
};
std::string getConfig()
{
std::stringstream buffer;
boost::property_tree::json_parser::write_json(buffer, _config);
return buffer.str();
};
bool valid = false;
private:
boost::property_tree::ptree _config;
};
Я видел несколько макросов, не уверен, что это правильный подход, кроме того, я еще не знаю, как его использовать.
Явная передача зависимостей — это хороший дизайн, я бы не стал этого менять. Интересно, почему вам нужно передавать его каждому методу, разве вы не передадите его конструктору использующих классов? Было бы интересно посмотреть, как вы используете эти настройки.
Вероятно, не всем другим классам нужен экземпляр класса Config, но большинству из них. Кажется, что передавать их конструкторам и сохранять в каждом классе неправильно. Но я могу ошибаться. Мне просто нужно читать и писать конфиги из разных классов. Никакой другой магии
Также мне нужен один и тот же экземпляр во всех этих классах. Поскольку он изменяется динамически
Я думаю, что на самом деле я буду передавать его каждому конструктору, в котором он мне нужен. Кажется, это наиболее контролируемый вариант.
Также неплохо иметь виртуальный класс конфигурации. Таким образом, вы можете смоделировать его в своих автоматических тестах и при необходимости изменить реализацию (например, использовать метод хранения информации, отличный от boost::ptree).
Зависит от фактического контекста использования, но если вы знакомы с шаблоном singleton, это может быть способом пойти здесь в сомнениях, если вы не можете пересылать информацию о конфигурации по замыслу совершенно ненавязчивым способом (последний должен почти всегда будет предпочтительным способом, но я знаю, что в реальности иногда бывают исключительные ситуации). Контекст синглтона не обязательно должен быть полностью глобальным, поскольку вы можете использовать глобальный синглтон, чтобы обеспечить более «контекстно-зависимое» ветвление, если это необходимо.
Но, как уже упоминалось: попробуйте решить это по дизайну, если контекст этой конфигурации не вызывает сомнений. Предоставьте, возможно, достаточно центральный класс обработчика (например, как sharedPtr), который предлагает данные конфигурации по запросу. Затем только конструкторы используемых объектов требуют его в качестве параметра.
Синглтон никогда не является решением. В конце концов вы поймете, что в некоторых местах вам нужна другая конфигурация. Или что вы хотели иметь модульные тесты для своего кода. И тогда вы пожалеете, что никогда не использовали синглтоны. Синглтоны — это в лучшем случае обходной путь, когда вам не хватает времени на рефакторинг для улучшения дизайна.
Хм, а вот почему, например, Скотт Мейерс объясняет их в различных книгах и статьях? Однозначно очень спорно обсуждаются синглтоны, но однозначно есть случаи, когда они действительно необходимы хотя бы из-за оценок отношения. Кроме того, если вы внимательно прочитаете мой ответ, вы должны понять, что я тоже сомневаюсь, что это самое надежное решение здесь.
@spectras PS: «Singleton никогда не бывает решением». Пожалуйста, не делайте субъективных мнений объективными фактами. Вы правы, что их часто не рекомендуют по уважительным причинам. Но оценка отношения — это один из часто недооцениваемых принципов разработки программного обеспечения, и для нескольких небольших проектов действительно идеальное дизайнерское решение — если оно существует — может потребовать непропорциональных ресурсов, вызывающих сомнение (где вы можете ухудшить ситуацию и стать подверженным ошибкам, если не будете делать это осторожно).
Когда вы заходите на сайт, который собирает экспертов, вы приходите на него, чтобы получить совет и опыт экспертов. Если бы мы ограничивали веб-сайт чисто объективными фактами, stackoverflow был бы просто указателем на другие авторитетные ресурсы. — а вот побуждать кого-то, у кого есть хороший и работающий дизайн, заменить его синглтоном — нонсенс, даже с дисклеймерами.
Я никого не призывал заменять работающий хороший дизайн на худший. Вопрос ОП касался подходов, ограничивающих пересылку чрезмерных параметров. В некоторых редких случаях синглтоны могут быть подходом, и это полностью зависит от сомнительного контекста, если это применимо. Я сказал это для полноты в первую очередь. Кроме того, существуют десятки надежных гибридных решений, которые значительно уменьшают недостатки полных глобальных синглетонов. Философские дискуссии о качестве паттерна/анти-паттерна концепции синглтона далее не по теме.
Можете ли вы передать ссылку на класс конфигурации в другие конструкторы классов, а затем сохранить ее в каждом классе как элемент данных?