【问题标题】:C++ Design of Entity & Manager Abstraction实体和管理器抽象的 C++ 设计
【发布时间】:2011-10-17 00:06:42
【问题描述】:

我正在编写一些代码来处理一组事件。这些事件可以根据它们的具体类型以不同的方式持久化。我目前有抽象事件的 iEvent 接口,可以持久化它们的每种方式的 iBackend 接口,以及每个后端的一组小接口(iFileEvent、iDBEvent 等),这些接口定义了从事件本身。每个具体事件类都实现 iEvent 以及它支持的任何能力接口组合。

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

问题是我没有为每个后端提供具体类型,因为 iBackend 接口只为它们提供了一个 iEvent。

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

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

当我只需要事件类来声明它们支持每个后端的接口时,添加类似乎毫无意义......这让我认为强制转换选项是前进的唯一途径。

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

【问题讨论】:

    标签: c++ design-patterns interface casting


    【解决方案1】:

    这里有一些解决方案:

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

      结构 Comb1 { 文件 f;事件1 e; Impl1 i1; };

      结构 Comb2 { Db d;事件1 e2; impl2 i3;};

      结构 Comb3 { 文件 f;事件2e; Impl1 i1; };

      结构 Comb4 { Db d;事件2e; Impl3 i1; };

    这些只是选择正确的实现来使用。

    然后为所有类构建基类:

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

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

    【讨论】:

      猜你喜欢
      • 2018-09-05
      • 1970-01-01
      • 1970-01-01
      • 2011-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多