C++ 解耦可视化方法及其应用

C++ 解耦可视化方法及其应用,c++,design-patterns,C++,Design Patterns,这是我关于SO的第一个问题,请耐心听我说 我们开发了一个收集数据的应用程序,我们有各种方法可以让数据以各种方式可视化。随着方法数量的增加,我们决定将应用程序和可视化方法分开。我想知道实现这一目标的最佳方式是什么。我想出了下面的代码,它试图将两者分开,但仍然 有更好的方法吗 // forward declaration class App; // Interface to all visualization methods struct Methods { virtual void sh

这是我关于SO的第一个问题,请耐心听我说

我们开发了一个收集数据的应用程序,我们有各种方法可以让数据以各种方式可视化。随着方法数量的增加,我们决定将应用程序和可视化方法分开。我想知道实现这一目标的最佳方式是什么。我想出了下面的代码,它试图将两者分开,但仍然

有更好的方法吗

// forward declaration
class App;

// Interface to all visualization methods
struct Methods {
    virtual void show(App * a) = 0;
};

// Some visualization method
struct Method0 : public Methods {
    void show(App * a) {
        a->getData();
    }
};

class App {
public:
    vector<Methods *> methods;

    void run() {
        // draw all registered methods
        for (auto m : methods)
            m->show(this);
    }

    int getData() {
        // parse and precompute data (time-consuming, thus do it only once)
        // return the required data (not just an int..)
        return 42;
    }
};

void main() {
    App a;

    // register some methods
    a.methods.push_back(new Method0());

    // run the application
    a.run();

    // clean up
    for (auto m : a.methods) delete(m);
}
//转发声明
类应用程序;
//所有可视化方法的接口
结构方法{
虚拟虚空显示(App*a)=0;
};
//几种可视化方法
结构方法0:公共方法{
无效显示(应用程序*a){
a->getData();
}
};
类应用程序{
公众:
向量法;
无效运行(){
//绘制所有注册的方法
用于(自动m:方法)
m->show(这个);
}
int getData(){
//解析和预计算数据(耗时,因此只需执行一次)
//返回所需的数据(不仅仅是int…)
返回42;
}
};
void main(){
应用程序a;
//注册一些方法
a、 方法:推回(新方法0());
//运行应用程序
a、 run();
//清理
对于(自动m:a.methods)删除(m);
}
编辑

我想亚历山大和彼得为我指明了正确的方向,谢谢。我将遵循Petr的建议,尝试将数据划分为另一个类

针对Spektre的评论:

  • 在Windows(MSVC)上开发,否则与平台无关
  • 可视化主要是静态的,并根据用户输入进行更改。我想每秒10次更新是刷新率的上限
  • 你所说的数据传输时间是什么意思
  • 记忆不是问题
数据是一组包含其他对象向量的对象向量,共5维

一个可视化类似于,包含多条曲线,因此我们需要遍历部分/所有维度并计算一些统计数据。结果如下图所示。

你那里的东西看起来已经很不错了。正如你可能已经假设的那样,你不是第一个有这种问题的人。将数据与可视化分离的标准解决方案称为,它不仅将数据的表示与数据本身分离,而且还允许从显示中对数据进行简单的操作


如果您只想显示数据,那么可能需要查看。再一次,你已经非常接近这个模式了。

除了Alexander的回答,我要提到的是,实际上你并没有完全分离数据和可视化。
应用程序
类仍然了解数据的内部结构和可视化方法的向量。你最好有一个单独的类,比如说
Data
,它将完成你需要的所有计算,然后有一个主类(
App
),它只处理方法的注册并将数据传递给它们

差不多

class Data;

struct Methods {
    virtual void show(Data * a) = 0;
};

struct Method0 : public Methods {
    void show(Data * d) {
        d->getData();
    }
};

class Data {
    public:
    int getData() {
        // parse and precompute data (time-consuming, thus do it only once)
        // return the required data (not just an int..)
        return 42;
    }
}

class App {
public:
    vector<Methods *> methods;
    Data* data;

    void run() {
        // draw all registered methods
        for (auto m : methods)
            m->show(data);
    }

};
类数据;
结构方法{
虚空显示(数据*a)=0;
};
结构方法0:公共方法{
无效显示(数据*d){
d->getData();
}
};
类数据{
公众:
int getData(){
//解析和预计算数据(耗时,因此只需执行一次)
//返回所需的数据(不仅仅是int…)
返回42;
}
}
类应用程序{
公众:
向量法;
数据*数据;
无效运行(){
//绘制所有注册的方法
用于(自动m:方法)
m->show(数据);
}
};

如果没有关于数据和可视化的背景信息,几乎不可能正确回答。在某些情况下,拆分是一个好主意,而在其他情况下则不是。所有这些都取决于许多因素,如编译器/平台约束、目标刷新率、数据传输时间、内存约束等。。。不知道你到底在做什么,我们帮不了你。添加更多信息一些数据样本和可视化输出示例,但这闻起来仍然像是基于意见的问题,即使您添加了所有信息,但至少我们可以建议一两件事…很好的问题,但不幸的是不适合SO格式。-问题是我们没有一个好的答案。