русский
Germany.ruForen → Архив Досок→ Programmierung

Глобально доступная информация

308  
  Chipolino свой человек19.03.09 23:02
NEW 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()

Жду ваших советов :-)

#1 
AlexOtt постоялец20.03.09 10:50
AlexOtt
NEW 20.03.09 10:50 
in Antwort Chipolino 19.03.09 23:02
берешь какой-нибудь готовый синглтон, пишешь свой класс, и оборачиваешь его в синглтон.
синглтон можно взять например вот отсюда - http://alexott-ru.blogspot.com/2008/01/singleton-boost.html
#2 
  scorpi_ прохожий20.03.09 10:58
20.03.09 10:58 
in Antwort Chipolino 19.03.09 23:02
В дополнение сказанному Алексом:
0. Классы CurrentItem и Info излишни, их имена неинформативны.
1. Убрать везде голые указатели, работать только с shared_ptr. Активный объект хранить как weak_ptr.
2. Зачем везде создавать CANDeviceFactory? Может её тоже сделать синглтоном?
#3 
  Chipolino свой человек20.03.09 12:04
NEW 20.03.09 12:04 
in Antwort AlexOtt 20.03.09 10:50
Метод currentItem сделан по образу и подобию синглета Майерса :-)
За ссылку спасибо .
#4 
  Chipolino свой человек20.03.09 12:20
NEW 20.03.09 12:20 
in Antwort scorpi_ 20.03.09 10:58
На детали реализации внимания не обращать , это код написаный на коленке :-)
В ответ на:
2. Зачем везде создавать CANDeviceFactory? Может её тоже сделать синглтоном?

В нормальной реализации так и есть , фабрики дергаются за статический instance метод .
В ответ на:
0. Классы CurrentItem и Info излишни, их имена неинформативны.

Имена не обсуждаются (см. выше) :-)
Видимо вы с Алексом меня не правильно поняли , мне просто нужно знать какой объект в данное время активен .
Например пользователь поменял тип контроллера(или ещё чего-нибудь) или зачитал новую конфигурацию ,
фабрики создали новые объекты , зарегистрировать эти объекты в каком-нибудь центральном месте , чтоб дергать
указатели на обьекты из него , а не каждый раз обращаться к фабрикам . Фабрика должна создавать объекты , не хочу
овбешивать её излишней функциональностью :-)
Хотя может у меня паранойя после прочтения GoF ...
#5 
  scorpi_ прохожий20.03.09 12:44
NEW 20.03.09 12:44 
in Antwort Chipolino 20.03.09 12:04
Вобще-то то предложение ревью не прошло.
#6 
  scorpi_ прохожий20.03.09 12:53
NEW 20.03.09 12:53 
in Antwort Chipolino 20.03.09 12:20
В ответ на:
мне просто нужно знать какой объект в данное время активен .
Например пользователь поменял тип контроллера(или ещё чего-нибудь) или зачитал новую конфигурацию ,
фабрики создали новые объекты , зарегистрировать эти объекты в каком-нибудь центральном месте , чтоб дергать
указатели на обьекты из него , а не каждый раз обращаться к фабрикам . Фабрика должна создавать объекты , не хочу
овбешивать её излишней функциональностью :-)

То бишь по сути каждый дивайс является синглтоном что ли? Что-то я совсем запутался. Можно о задаче поподробнее, вообще не затрагивая реализацию?
#7 
Murr коренной житель20.03.09 17:29
Murr
NEW 20.03.09 17:29 
in Antwort scorpi_ 20.03.09 12:53
То бишь по сути каждый дивайс является синглтоном что ли?
-----
Вроде нет.
Как Я понял - куча разнородных девайсов, из которых в каждый конкретный момент активен только один. Ему нужно знать какой именно активен.
Если так, то ему нужно не ClassFactory мучать, а создавать/перекрывать метод, который будет менять текущий активный девайс. Если девайсы совершенно разнотипные и/или их код модифицировать нельзя, то придется делать какой-то (возможно - пустой) врапер для оборачивания текущего и его сохранять...
#8