Aрхитектура приложения

333
15 января 2017, 16:39

Сразу прошу прощения за такой заголовок, я просто не знаю, как в двух словах описать проблему.

Ситуация следующая. Допустим, есть некий класс "рабочее место":

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;
//...
};

Теоретически он может выступать в роли посредника, однако я пока не придумал как это может мне помочь.

Answer 1

Ну, можно, например, держать одну большую таблицу с записями "работник/рабочее место" и при необходимости выполнять поиск в ней. Для небольшого количества записей - ну, там, тысячи - обычный вектор пар будет вполне адекватен. Если гораздо больше - можно подумать об ассоциативных контейнерах (типа, multimap может оказаться подходящим решением).

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

Задача скорее из БД :)

READ ALSO
Работа со службами из программы со стандартными полномочиями

Работа со службами из программы со стандартными полномочиями

Имеется следующая ситуация: 1Работаем под OS поддерживающими UAC

315
Проблемы с реализацтей Entity–component–system Design Pattern [требует правки]

Проблемы с реализацтей Entity–component–system Design Pattern [требует правки]

Реализовал ECS pattern на примере игрыПока была одна сущность - Игрок (Player) было все хорошо, создал 10 компонентов Position, SpriteSheet, State, Movable, MovableMod, Controller,...

344
Рекурсивная функция

Рекурсивная функция

Дано натуральное число nВыведите все числа от 1 до n

353