2010-11-09 58 views
0

好的,我似乎需要从基础向前推导派生,我认为这可能是一个设计问题,所以我会解释我在做什么,你可以告诉我我需要改变什么。 XML文件定义了一堆类似的对象。他们共享相同的基类。主函数在基类DoWork()中定义,并且是虚拟的。设计我的程序,以避免必须从基础派生到派生类

我的程序加载XML文件并创建派生类并将它们分配给基类类型的向量。

一切都很棒的程序工作。我可以遍历矢量并调用DoWork();

现在,我添加了一个GUI层,以便您可以修改对象并写回一个XML文件。所以,现在我的GUI代码可以访问基类指针的向量。但是,这是不好的,因为我需要来自派生类的信息,所以我可以写出XML文件。这是动态铸造的唯一解决方案吗?我能否以某种方式改变设计?我知道从基地铸造派生是皱眉。

编辑:我的GUI需要显示派生类也有信息。只有一个序列化类是不够的。

回答

3

有两种不同的方法,你可以在这里。第一个是提供一个虚拟方法来生成与元素相对应的XML。

第二种方法是提供一个访问者接口:基本上你定义了一个接受visitor类型的虚拟方法。访客类型将在层次结构的每个级别用当前对象调用,从而生成一种双重调度机制。通过这种方式,虚拟调度将解析为最派生的对象,这将调用访问者对象来序列化自己。

第一种方法更简单,而第二种方法具有层次结构中每个对象与实际序列化格式之间松散耦合的优点。也就是说,您可以生成不同的访问者,这些访问者可以序列化为不同的格式,而无需修改当前层次结构中的代码。

+1

+1,我很惊讶这是迄今为止唯一的解决方案(6分)提及访问。 – 2010-11-09 15:19:39

4

您可以添加例如对每个类使用虚拟的serialize方法,以便您的输出循环可以遍历该向量,并在每个元素的基指针上调用(*it)->serialize()

0

要么在派生类可以重写的基类中实现一个函数,以公开必要的信息来写出Xml,或者让对象本身持久化到Xml。这两种解决方案都不需要你知道它是什么。

1

您可以在您的基类中定义一个将对象打印为XML的方法,然后让所有派生类都提供它们自己的实现。基本上,你会委派打印到派生类。

编辑:或者更一般地说,遵循奥利的建议,并写了serialize()方法返回该对象的重要数据元素的容易消化的集合(例如,键值对的列表)的基础类。然后,您的主程序可以迭代每个对象的序列化表单并决定如何处理它。

0

如果您在基类中定义了相同的行为,您需要使用该行为来获取派生类中的数据,则可以将所有对象视为相同。对于以前没有这种行为的派生类,您可以让它们默默失败。看看复合设计模式的意图。

1
  1. 张贴小代码示例 -

  2. 听起来就像是基类需要一个虚拟的中WriteXML() - 纯粹的在这一点猜测