2010-08-24 3 views
2

В текущем проекте есть много методов GetData(), которые получают разные данные из ручной письменной базы данных во время выполнения, и устанавливают их в разных полях в классе. Тогда у проектов есть такие методы.Как оптимизировать/реорганизовать такой код?

void GetData(Datatype type, int& value); 
void GetData(Datatype type, double& value); 
void GetData(Datatype type, long& value); 
void GetData(Datatype type, longlong& value); 
.... 

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

void GetData(Datatype type, int& value) 
{ 
    switch(type) 
    { 
     Type1: 
     value = GetDataFromDB1(TYPE1); 
     Type2: 
       value = .. //get from different source 
     ... 

    } 

}

void GetData(Datatype type, double& value) 
.... 

Как вы видите, тем GetData() s классифицируются в соответствии со вторыми парами. И внутри каждого GetData() есть много ветвей. Является ли это разумным методом получения данных?

+4

Слишком мало контекста, чтобы даже получить обоснованное предположение, но, похоже, это воняет необходимостью в шаблонах. – sbi

+0

'boost :: any'? Или, может быть, «boost :: variant»? – jalf

ответ

2

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

0

К сожалению, Java программист приходит :)
У меня есть 2 решения здесь:

  1. Если вы хотите изменить код не так много, вы могли бы поставить свои типы данных и соответствующие операции в Карта. До сих пор switch(type) заявление могло быть известие map.get(type).

  2. Если более приличный способ, используйте Полиморфизм. Вы можете определить интерфейс для DBOperations, каждый из DBOperation может быть , определенный в его реализованном классе. Так GetData просто нужно для вызова Интерфейс DBOperation. Это грубая идея .

-1

Не уверен, если я понял это правильно, но это может помочь

typedef int Datatype; 

template <Datatype d, class T> struct Wrap{ 
    Wrap(T (*p)(Datatype)) : mp(p){} 
    template<class T> void GetData(T &value){ 
     value = (*mp)(d); 
    }; 
    T (*mp)(Datatype); 
}; 

int GetDataFromDB(Datatype){ 
    return 0; 
} 

int main(){ 
    Wrap<0, int> wi0(GetDataFromDB); 
    int val; 
    wi0.GetData(val); 
} 
+0

Как только у вас есть тип, зафиксированный в шаблоне 'Warp', вы можете изменить' GetData() ', который будет использоваться более легко:' int val = w10.GetData() '. Передача его как аргумента функции была очень вероятна только для облегчения вывода аргумента шаблона. – sbi

+0

@sbi: правда, однако я старался как можно больше синхронизировать с исходным кодом (который возвращает значение по ссылке – Chubsdad

+1

-1: введение набора объектов в соответствие 1: 1 с существующими функциями не является рефакторингом. Это просто обфускация. – Potatoswatter

0

Похоже, вы перерастает настраиваемый пользовательский интерфейс SQL. Изучите существующие библиотеки C++ SQL. К сожалению, я не могу рекомендовать (в прошлый раз, когда я нуждался в нем, я написал новый по глупым большим расходам), но см. Соответствующий вопрос C++ SQL database library comparison.

Также, libpqxx, официальный клиент C++ PostgreSQL, выглядит очень красиво.

Хм, оглядываясь, я не могу найти библиотеку с общей поддержкой для struct. Мне нравится то, что я написал. Там должно быть что-то там ... вы должны иметь возможность подключать свои таблицы и заголовки (возможно, немного модифицировать) и получить код автоматического интерфейса.

0

Возможно, вы захотите реорганизовать его, чтобы сделать его более удобным.

Рефакторинг для оптимизации, вероятно, не принесет никакой пользы или негатива, если вы не показали, что это проблема производительности, путем профилирования.

Смежные вопросы