Вход на сайт
Глобально доступная информация
308
19.03.09 23:02
Как наиболее элегантно организовать доступ к данным , которые должны быть глобально доступны ? ( Ахтунг дальше плюсы)
У меня есть несколько фабрик , и мне нужно из многих мест в программе знать, какой объект активен.
Пока вот что придумал :
Имеем небольшую иерархию
У меня есть несколько фабрик , и мне нужно из многих мест в программе знать, какой объект активен.
Пока вот что придумал :
Имеем небольшую иерархию
struct CANDevice
{
virtual ~CANDevice() {}
};
struct CANDevice1:public CANDevice
{
};
struct CANDevice2:public CANDevice
{
};
Фабрика
class CANDeviceFactory
{
public:
typedef CANDevice* (*Creator)();
CANDeviceFactory()
{
registerDevice("device 1" , &createCANDevice<CANDevice1>);
registerDevice("device 1" , &createCANDevice<CANDevice2>);
}
shared_ptr<CANDevice> create(std::string const & id)
{
return shared_ptr<CANDevice>(creators_[id]());
}
void registerDevice(std::string const & id,Creator creator)
{
creators_[id]=creator;
}
private:
std::map<std::string, Creator> creators_;
};
И собственно в функции креаторе регистрируем объект
template<class CANDeviceType>
CANDevice* createCANDevice()
{
CANDevice* device = new CANDeviceType();
Info::current<CANDevice>().set(device); // смотри ниже
return device;
}
И теперь класс Info
template<class T>
class CurrentItem
{
public:
T* get() { return item_;}
void set(T* item) { item_=item; }
private:
T* item_;
};
class Info
{
public:
template<class T>
static CurrentItem<T> & current()
{
static CurrentItem<T> item;
return item;
}
};
Где-нибудь в коде
CANDeviceFactory factory;
factory.create("device 1");
// теперь с любого места в программе
Info::current<CANDevice>().get()
Жду ваших советов :-)
NEW 20.03.09 10:58
в ответ Chipolino 19.03.09 23:02
В дополнение сказанному Алексом:
0. Классы CurrentItem и Info излишни, их имена неинформативны.
1. Убрать везде голые указатели, работать только с shared_ptr. Активный объект хранить как weak_ptr.
2. Зачем везде создавать CANDeviceFactory? Может её тоже сделать синглтоном?
0. Классы CurrentItem и Info излишни, их имена неинформативны.
1. Убрать везде голые указатели, работать только с shared_ptr. Активный объект хранить как weak_ptr.
2. Зачем везде создавать CANDeviceFactory? Может её тоже сделать синглтоном?
NEW 20.03.09 12:20
в ответ scorpi_ 20.03.09 10:58
На детали реализации внимания не обращать , это код написаный на коленке :-)
В нормальной реализации так и есть , фабрики дергаются за статический instance метод .
Имена не обсуждаются (см. выше) :-)
Видимо вы с Алексом меня не правильно поняли , мне просто нужно знать какой объект в данное время активен .
Например пользователь поменял тип контроллера(или ещё чего-нибудь) или зачитал новую конфигурацию ,
фабрики создали новые объекты , зарегистрировать эти объекты в каком-нибудь центральном месте , чтоб дергать
указатели на обьекты из него , а не каждый раз обращаться к фабрикам . Фабрика должна создавать объекты , не хочу
овбешивать её излишней функциональностью :-)
Хотя может у меня паранойя после прочтения GoF ...
В ответ на:
2. Зачем везде создавать CANDeviceFactory? Может её тоже сделать синглтоном?
2. Зачем везде создавать CANDeviceFactory? Может её тоже сделать синглтоном?
В нормальной реализации так и есть , фабрики дергаются за статический instance метод .
В ответ на:
0. Классы CurrentItem и Info излишни, их имена неинформативны.
0. Классы CurrentItem и Info излишни, их имена неинформативны.
Имена не обсуждаются (см. выше) :-)
Видимо вы с Алексом меня не правильно поняли , мне просто нужно знать какой объект в данное время активен .
Например пользователь поменял тип контроллера(или ещё чего-нибудь) или зачитал новую конфигурацию ,
фабрики создали новые объекты , зарегистрировать эти объекты в каком-нибудь центральном месте , чтоб дергать
указатели на обьекты из него , а не каждый раз обращаться к фабрикам . Фабрика должна создавать объекты , не хочу
овбешивать её излишней функциональностью :-)
Хотя может у меня паранойя после прочтения GoF ...
20.03.09 12:53
То бишь по сути каждый дивайс является синглтоном что ли? Что-то я совсем запутался. Можно о задаче поподробнее, вообще не затрагивая реализацию?
в ответ Chipolino 20.03.09 12:20
В ответ на:
мне просто нужно знать какой объект в данное время активен .
Например пользователь поменял тип контроллера(или ещё чего-нибудь) или зачитал новую конфигурацию ,
фабрики создали новые объекты , зарегистрировать эти объекты в каком-нибудь центральном месте , чтоб дергать
указатели на обьекты из него , а не каждый раз обращаться к фабрикам . Фабрика должна создавать объекты , не хочу
овбешивать её излишней функциональностью :-)
мне просто нужно знать какой объект в данное время активен .
Например пользователь поменял тип контроллера(или ещё чего-нибудь) или зачитал новую конфигурацию ,
фабрики создали новые объекты , зарегистрировать эти объекты в каком-нибудь центральном месте , чтоб дергать
указатели на обьекты из него , а не каждый раз обращаться к фабрикам . Фабрика должна создавать объекты , не хочу
овбешивать её излишней функциональностью :-)
То бишь по сути каждый дивайс является синглтоном что ли? Что-то я совсем запутался. Можно о задаче поподробнее, вообще не затрагивая реализацию?
NEW 20.03.09 17:29
в ответ scorpi_ 20.03.09 12:53
То бишь по сути каждый дивайс является синглтоном что ли?
-----
Вроде нет.
Как Я понял - куча разнородных девайсов, из которых в каждый конкретный момент активен только один. Ему нужно знать какой именно активен.
Если так, то ему нужно не ClassFactory мучать, а создавать/перекрывать метод, который будет менять текущий активный девайс. Если девайсы совершенно разнотипные и/или их код модифицировать нельзя, то придется делать какой-то (возможно - пустой) врапер для оборачивания текущего и его сохранять...
-----
Вроде нет.
Как Я понял - куча разнородных девайсов, из которых в каждый конкретный момент активен только один. Ему нужно знать какой именно активен.
Если так, то ему нужно не ClassFactory мучать, а создавать/перекрывать метод, который будет менять текущий активный девайс. Если девайсы совершенно разнотипные и/или их код модифицировать нельзя, то придется делать какой-то (возможно - пустой) врапер для оборачивания текущего и его сохранять...