实体的C ++设计&经理抽象

时间:2011-07-31 18:05:00

标签: c++ design-patterns interface casting

我正在处理一些代码来处理一组事件。这些事件可以根据其具体类型以不同方式持久化。我目前有iEvent接口抽象事件,iBackend接口用于它们可以被持久化的每种方式,以及一组用于每个后端的小接口(iFileEvent,iDBEvent等),它们定义了转换方法到所需的序列化表示。事件本身。每个具体事件类都实现了iEvent及其支持的任何功能接口组合。

这在反序列化时工作正常,因为这是由后端实现(文件,数据库等)执行的,因此他们知道从现有内容创建的具体事件类型,因此可以使用具体事件类的公共创建它们的方法。然而,我现在正处于需要序列化新事件的地步,并且有点窘迫。

问题在于我没有为每个后端提供具体类型,因为它们只是由于iBackend接口而被赋予了iEvent。

我可以使用dynamic_cast,或者我可以使用rtti比较(或更便宜的版本)和static_cast,但我不确定是否有更好的查询能力的方法,而且我不知道看看用这些建议解决这个问题的干净方法。

我希望在具体事件类型和用于在每个后端中持久保存它们的数据结构之间进行转换的具体情况可以通过后端中的一组方法为每种类型的事件实现,但我不喜欢所有...但是每个类和后端组合的一组转换装饰器都闻起来像一个讨厌的类爆炸案例。

当我需要的只是事件类来表示它们支持每个后端的接口时,似乎毫无意义的添加类...这使我认为转换选项是唯一的前进方式。

总而言之,我正在寻找更好解决方案的建议。

1 个答案:

答案 0 :(得分:0)

这是一些解决方案:

  1. 保持{file,db} * {Event1,Event2}
  2. 的爆炸式增长
  3. 但不是为每个组合创建单独的类,而是尝试构建适用于多个组合的类。
  4. 然后您的代码只列出了所有组合,但为每个组合创建了以下类型的结构:

    struct Comb1 {File f; Event1 e; Impl1 i1; };

    struct Comb2 {Db d; Event1 e2; Impl2 i3;};

    struct Comb3 {File f; Event2 e; Impl1 i1; };

    struct Comb4 {Db d; Event2 e; Impl3 i1; };

  5. 这些只是选择正确的实施方式。

    然后为所有类构建基类:

    struct Generic { FileDbBase *ptr; EventBase *base; ImplBase *impl; };
    

    然后创建一个2d的泛型数组,由{file,db}和{Event1,Event2}索引。此结构允许您重用现有实现。将Comb1,Comb2,Comb3,Comb4的实例添加到2d数组中。