【问题标题】:How can I avoid semantic coupling to create a reusable display engine?如何避免语义耦合以创建可重用的显示引擎?
【发布时间】:2013-10-23 12:22:48
【问题描述】:

DisplayEngine 有一个 DisplayableObjects 列表。每个 DisplayableObject 派生类使用不同的数据集。因此,我为数据创建了一个基类,这样我就可以将 BaseData 传递到每个 DisplayableObject 的更新中,而无需了解有关 DisplayableObject 和 BaseData 派生类的任何信息。然后在每个派生的 DisplayableObject 更新函数中,我转换为正确的数据类型。

问题在于这是一种语义耦合。如果我将错误的派生数据类传递给派生的 DisplayableObject 类之一,这就会崩溃,而且更新函数真的不能像在外部看到的那样处理所有 BaseData 类。

基本上这里发生的事情是 Module1 将 BaseObject 传递给 Module2。因为 Module2 知道 Module2 确实传递给它 DerivedObject,所以它将 BaseObject 转换为 DerivedObject 并使用特定于 DerivedObject 的数据。

问题是,我想不出任何其他方式来做到这一点。如何拥有一个 DisplayableObjects 列表,每个都采用不同的数据集,并且让 DisplayEngine 对任何派生类一无所知,以便我可以在另一个项目中重用 DisplayEngine?

这有点复杂,所以提前感谢您查看它。

Class DisplayEngine{
    DisplayableObject displayableObjectsList[10];
    BaseData *dataList[10];
    // Each element in data list is updated somewhere else.

    void UpdateAll(){
        for(int i=0; i<10; i++){
            displayableObjectsList[i].Update(dataList[i]);
        }
    }
}

Class DisplayableObject{
    virtual void Update(BaseData bData);
}

Class BaseData {
    //empty.
}

Class Data1 : BaseData{
    String b;
}

Class Data2: BaseData{
    int a;    
}

Class DisplayableObject1: DisplayableObject{
    void Update(BaseData bData){
        Data1* d = (Data1*) bData;
        //Do Work with d, can use d.b
    }
}

Class DisplayableObject2: DisplayableObject{
    void Update(BaseData bData){
        Data2* d = (Data2*) bData;
        //Do Work with d, can use d.a
    }
}

【问题讨论】:

    标签: c++ code-reuse coupling


    【解决方案1】:

    尝试使用访客模式。 您可以阅读所有相关信息here

    如果您有更多问题或需要更多示例,请随时提问。

    【讨论】:

    • 感谢您的回复。我以前没有听说过访问者模式,虽然我不确定它是否会在这里工作,但它非常有趣。在这种模式中,访问者需要为每种元素类型实现一个方法。在我的例子中,我的 displayableObjects 列表不需要对每个 baseData 派生类型做不同的事情,它只处理其中一个。每个 displayableObject 将显示来自一个 baseData 派生数据类的数据。但是,我可能能够在此处的解决方案中使用访问者模式中的一些概念,我将不得不花更多时间来处理它。再次感谢!
    • 只需在基础中实现一个空实现,并覆盖一种方法 fly hat 处理您的特定数据类型。
    • 对,可以!我能预见的唯一问题是在大型项目中,您有大量的可显示对象,因此数据类,每次添加新对象时,您最终都必须修改每个对象。这会使添加新的显示对象非常耗时。有什么建议吗?
    • 您所要做的就是在基础中添加前向声明和一个空实现。但你是对的,不断更新基类是模式的缺点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-02
    • 2011-08-12
    • 1970-01-01
    • 2012-05-02
    • 1970-01-01
    • 2015-01-27
    相关资源
    最近更新 更多