моя среда: Ubuntu 15.10, 64-битная, g ++ V5
я проблема в том, что мое приложение может иметь много пользовательского ввода, который определяет, как приложение будет запущено. Приложение представляет собой систему базы данных в памяти, и пользователь может, например, вызвать программу с помощью команд, таких как '--pagesize 16384' (устанавливает размер страницы памяти для использования), '--alignment 4096' (устанавливает выравнивание памяти для использования) или --memeasure (устанавливает флаг для измерения определенных подпрограмм).
В настоящее время я сохраняю весь пользовательский ввод в глобальных переменных, которые определены как extern в заголовочном файле:
//@file common.hh
extern size_t PAGE_SIZE_GLOBAL;
extern size_t ALIGNMENT_GLOBAL;
extern size_t MEMCHUNK_SIZE_GLOBAL;
extern size_t RUNS_GLOBAL;
extern size_t VECTORIZE_SIZE_GLOBAL;
extern bool MEASURE_GLOBAL;
extern bool PRINT_GLOBAL;
extern const char* PATH_GLOBAL;
и в основном исходном файле:
#include "modes.hh"
size_t PAGE_SIZE_GLOBAL;
size_t ALIGNMENT_GLOBAL;
size_t MEMCHUNK_SIZE_GLOBAL;
size_t RUNS_GLOBAL;
size_t VECTORIZE_SIZE_GLOBAL;
bool MEASURE_GLOBAL;
bool PRINT_GLOBAL;
const char* PATH_GLOBAL;
int main(const int argc, const char* argv[]){
...
//Initialize the globals with user input
PAGE_SIZE_GLOBAL = lArgs.pageSize();
ALIGNMENT_GLOBAL = lArgs.alignment();
MEMCHUNK_SIZE_GLOBAL = lArgs.chunkSize();
RUNS_GLOBAL = lArgs.runs();
VECTORIZE_SIZE_GLOBAL = lArgs.vectorized();
MEASURE_GLOBAL = lArgs.measure();
PRINT_GLOBAL = lArgs.print();
std::string tmp = lArgs.path() + storageModel + "/";
PATH_GLOBAL = tmp.c_str();
...
}
Затем я включаю заголовочный файл common.hh в каждый файл, где требуется глобальная переменная (которая может быть очень глубоко в системе).
Я уже прочитал дюжину раз, чтобы предотвратить глобальные переменные, так что это явно плохой стиль. В книге «Code Complete 2» от Стива Макконнелла также говорится, что глава о глобальных переменных запрещает глобальные переменные и вместо этого использует процедуры доступа. В разделе «Как использовать процедуры доступа» он пишет
«Скрыть данные в классе. Объявите эти данные с помощью статического ключевого слова (...), чтобы убедиться, что существует только один экземпляр данных. Напишите процедуры, которые позволят вам посмотреть на данные и изменить их».
Прежде всего, глобальные данные не изменятся (возможно, это изменится позже, но, по крайней мере, не в ближайшем будущем). Но я не понимаю, как эти процедуры доступа лучше? У меня также будет класс, который мне нужно включить в каждый файл, где нужны данные. Разница лишь в том, что глобальные данные - это статические члены, доступ к которым осуществляется через функции получения.
(Отредактировано) Я также подумал об использовании глобального класса данных Singleton. Но объект со ВСЕМИ глобальными данными звучит излишне, поскольку в его разных местах назначения требуется всего несколько глобальных переменных объекта.
Мой вопрос: я должен просто придерживаться глобальных переменных? Есть ли лучшие решения, чего мне не хватает? Каковы лучшие практики?
Редактировать: Если бы я определил несколько классов, где пользовательский ввод нужен больше всего, я мог бы изменить глобальные данные на переменные-члены. Какова была бы лучшая практика для передачи пользовательского ввода в эти классы? Передача данных в качестве параметров через всю систему до самых нижних слоев звучит неправильно. Есть ли шаблон дизайна (думая о чем-то похожем на фабрику), который подойдет здесь?