Сразу прошу прощения за такой заголовок, я просто не знаю, как в двух словах описать проблему.
Ситуация следующая. Допустим, есть некий класс "рабочее место":
class Workplace{
};
и класс "работник", который знает, к какому рабочему месту он относится:
class Worker{
Workplace *_workplace;
public:
explicit Worker(Workplace *workplace):
_workplace(workplace)
{}
};
В процессе разработки оказалось, что было бы хорошо, если бы Workplace
знал список всех, кто на нем работает. Наподобие того, как QObject
знает список всех своих детей. Сделано это было примерно так:
class Worker;
class Workplace{
std::vector<Worker*> _workers;
public:
const std::vector<Worker*>& workers() const{
return _workers;
}
private:
friend class Worker;
void _add(Worker *worker){
_workers.push_back(worker);
}
void _remove(Worker *worker){
_workers.erase(std::remove(_workers.begin(), _workers.end(), worker), _workers.end());
}
};
class Worker{
Workplace *_workplace;
public:
explicit Worker(Workplace *workplace)
{
setWorkplace(workplace);
}
void setWorkplace(Workplace *workplace){
if(_workplace == workplace){
return;
}
if(_workplace){
_workplace->_remove(this);
}
if(workplace){
workplace->_add(this);
}
_workplace = workplace;
}
~Worker(){
setWorkplace(0);
}
};
Если в двух словах: каждый раз, когда у работника меняется рабочее место, он сообщает старому, что он больше там не работает, и новому - что он там работает.
В таком небольшом примере все вроде бы работает как надо. Однако классов у меня гораздо больше, и код получился весьма запутанным. Может, кто-нибудь знает более элегантное решение этой проблемы? Ну или хотя бы её название, если оно есть.
PS: Есть еще класс, который содержит в себе весь этот зоопарк, назовем его Company
:
class Company{
std::vector<Worker*> _workers;
std::vector<Workplace*> _workplaces;
//...
};
Теоретически он может выступать в роли посредника, однако я пока не придумал как это может мне помочь.
Ну, можно, например, держать одну большую таблицу с записями "работник/рабочее место" и при необходимости выполнять поиск в ней. Для небольшого количества записей - ну, там, тысячи - обычный вектор пар будет вполне адекватен. Если гораздо больше - можно подумать об ассоциативных контейнерах (типа, multimap
может оказаться подходящим решением).
Если скорость критична - тогда надо жертвовать простотой и в каждом классе иметь соответствующие поля и при смене выполнять обновления - при большой запутанности, возможно, каскадные.
Задача скорее из БД :)
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Имеется следующая ситуация: 1Работаем под OS поддерживающими UAC
Реализовал ECS pattern на примере игрыПока была одна сущность - Игрок (Player) было все хорошо, создал 10 компонентов Position, SpriteSheet, State, Movable, MovableMod, Controller,...