LINUX.ORG.RU

Правильное архитектурное решение

 , , ,


0

3

Есть вот такая архитектура на моем текущем проетке.

class WebsocketsStream {

};

class Data {

};

class Configuration {

};

class DeviceDataListener {

};

class BaseDeviceListener {
    virtual void receive_data(Data* data) = 0;
    virtual void receive_processed_data(Data* data) = 0;
};

class DataReceiverDevice {
    public:
        void register_data_listener(BaseDeviceListener* data_listener);
};

class DeviceListener;
class Device {
public:
    Device(DataReceiverDevice* dd) : dd_(dd), device_listener_(new DeviceListener(dd)) { dd_->register_data_listener(device_listener) }
    void receive_processed_data(Data* data) {
        for (auto &listener : device_listeners_) {
            listener->receive_processed_data(data);
        }
    }
    void receive_data(Data* data) {
        for (auto &listener : device_listeners_) {
            listener->receive_data(data);
        }
    }

private:
    DataReceiverDevice* dd_;
    DeviceListener* device_listener_;
    std::vector<std::shared_ptr<DeviceDataListener>> device_listeners_;
};

class DeviceListener : public BaseDeviceListener {
public:
    void receive_data(Data* data) { device_->receive_data(data);
    void receive_processed_data(Data* data) { device_->receive_processed_data(data);  
}
    DeviceListener(Device* device) : device_(device) {}
private:
    Device* device_;
};

class OscOutputConfiguration : public Configuration {
    private:
        Device* device_;
};

class LocalFileOutputConfiguration : public Configuration {
    private:
        Device* device_;
};

class WebsocketsOutputConfiguration : public Configuration {
    private:
        Device* device_;
        WebsocketsStream* w_stream;
};

Есть Device класс, который получает данные от DataReceiverDevice с помощью обсервер паттерна у которого есть выходные конфигурации: одна для записи данных в файл, вторая для посылки данных на другой девайс через блютуз.

У класса Device мы регистрируем listener с помощью метода register_data_listener() для DataReceiverDevice и мы оттуда получаем данные вызывая метод receive_data(). Также у девайса есть вектор слушателей который отправляет данные наверх. Когда класс Device получает данные он их отправляет всем листенерам.

Мне понадобилось сделать дополнительную конфигурацию WebsocketsOutputConfiguration чтобы отправлять данные по вебсокетам и принимать уже обработанные данные. Эта конфигурация как входная так и выходная.

И вот сейчас я в раздумьях как мне достучаться до Device объекта из WebsocketsStream, чтобы вызвать его методы о получении данных и соответсвенно обновлять всех listener'ов. Можно передать тот же device_listener_ который у нас есть уже в классе Device ниже по иерархии, он уже содержит ссылку на девайс в себе и можно дернуть скажем новый метод receive_processed_data? Просто каждая конфигурация уже содержит в себе Device объект? Как вы считаете, как сделать это в рамках данной архитектуры более правильно?

если вы уже более 5 лет работаете разработчиком, то лучше смените род занятий

anonymous ()
Ответ на: комментарий от anonymous

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

ECLIPSE ()
Ответ на: комментарий от ECLIPSE

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

anonymous ()
Ответ на: комментарий от anonymous

вы уже не должны ничего спрашивать или консультироваться

Никто и никому ничего не должен. Прям вот совсем и целиком да полностью. Даже сверх-супер специалист с гордым бейджиком на цветной ленточке почётного участника очередной мега конференции по цепепе или сверх супер нагруженных систем, витающих далеко в облаках S3, S4 и S5 и даже S6, в докерах-шмокерах, кубернетесах и пубертатусах, может задать элементарный вопрос в части ОО-дизайна своего велосипеда. Делов то.

azelipupenko ()
    Device(DataReceiverDevice* dd) : dd_(dd), device_listener_(new DeviceListener(dd)) { dd_->register_data_listener(device_listener) }
....
    DataReceiverDevice* dd_;
    DeviceListener* device_listener_;
    std::vector<std::shared_ptr<DeviceDataListener>> device_listeners_;

Я бы начал с этого. Кто тут должен владеть dd_, device_listener_ и нужен ли тут вообще вектор шаред поинтеров. Как минимум device_listener_ у тебя утечет.

ОСтальное перечитал несколько раз и так не понял чем отличается WebsocketsOutputConfiguration от остальных.

xpahos ★★★★★ ()
Ответ на: комментарий от anonymous

ошибаешся, дужок. пруф

Ты пропустил мягкий знак :-) Садись, два :-) Лол :-)

azelipupenko ()

У меня для подобных ситуаций есть один трюк. Когда я чувствую, что с архитектурой что-то не то - я переписываю все на чистых сях as simple as possible. Не раз выручало.

anonymous ()

А по теме. ОП, у тебя какая-то сложная конфигурация классов. Без знания предметной области мне сложно судить, как ее упростить. Но у тебя проблема между data-listener-device-socket, а классов для понимая проблемы задействуется 12. Тут что-то не так. Попробуй упростить. Плодить по классу на каждый чих - плохая практика. Например, зачем так много конфигураций и наследований между ними? В чем разница между DeviceListener и BaseDeviceListener? Ты практическую задачу решаешь или пишешь суперуниверсальный фреймворк для всего-всего?

Aswed ★★★★★ ()
Ответ на: комментарий от Aswed

по существу и дураку понятно что в своих соплях может разобраться только хозяин

anonymous ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.