设计类:每个类封装其他相关类的对象



我被设计问题卡住了。我想不出任何好的解决办法。下面是问题说明。

我有一组设备,每一个设备都有一些共同的属性和行为。每个设备可以包含一个或多个其他类型的设备连接到它。例如:如果有4组设备A,B,C,D和A是所有设备的根。

A will have one or many B devices.
B will have one or many C devices.
C will have one or many D devices.

所有这些不同的设备都有一些共同的属性,而有些则是它们自己独有的。

I have to create a report which will read the data from these objects and read it to file. Report is in XML format and will depict hierarchy of whole system.

我该如何解决这个问题?任何建议和评论都将大有帮助。

这听起来像是访问者模式的一个例子。让访问者访问A的每个子节点。对于每个子节点,它将再次访问所有子节点,以此类推。

当Visitor遍历树时,收集每个节点的数据。例如,在这种情况下,如果您愿意,可以直接在XML中收集数据。

访问者模式可以很好地处理异构数据类型,但是当一些节点也具有公共结构时也可以。

访问者模式是一种更好的执行操作的方式,所有的父类和子类都应该被接受作为输入,其中的行为由对象类型决定。

这里是c++实现供参考:

#include <vector>
#include <iostream>
using namespace std;
class Visitor
{
  public:
    virtual void visit(class Node *, class Common*) = 0;
    virtual void visit(class CompositeNode *, Common*) = 0;
};
class Common
{
    int value;
  public:
    Common(int val)
    {
        value = val;
    }
    virtual void traverse()
    {
        cout << value << " | ";
    }
    virtual void accept(Visitor &, Common*) = 0;
};
class Node: public Common
{
  public:
    Node(int val): Common(val){}
     virtual void accept(Visitor &v, Common *c)
    {
        v.visit(this, c);
    }
};
class CompositeNode: public Common
{
    vector < Common * > children;
  public:
    CompositeNode(int val): Common(val){}
    void add(Common *ele)
    {
        children.push_back(ele);
    }
     virtual void accept(Visitor &v, Common *c)
    {
        v.visit(this, c);
    }
     virtual void traverse()
    {
        Common::traverse();
        for (int i = 0; i < children.size(); i++)
          children[i]->traverse();
    }
};
class AddVisitor: public Visitor
{
  public:
     virtual void visit(Node *, Common*)
    {
    }
     virtual void visit(CompositeNode *node, Common *c)
    {
        node->add(c);
    }
};
int main()
{
  Common *nodes[3];
  nodes[0] = new CompositeNode(0); //Consider A
  nodes[1] = new CompositeNode(1); //Consider B
  nodes[2] = new CompositeNode(2); //Consider B
  AddVisitor addVisitor;
  nodes[0]->accept(addVisitor, nodes[1]); //B
  nodes[0]->accept(addVisitor, nodes[2]); //B
  nodes[1]->accept(addVisitor, new Node(3)); //Consider C
  nodes[1]->accept(addVisitor, new Node(4)); //Consider C
  nodes[2]->accept(addVisitor, new Node(5)); //Consider C
  nodes[2]->accept(addVisitor, new Node(6)); //Consider C
  for (int i = 0; i < 3; i++)
  {
    cout<<"--------------------------------"<<endl;
    nodes[i]->traverse();
    cout<<endl;
  }
}

--------------------------------
0 | 1 | 3 | 4 | 2 | 5 | 6 |
--------------------------------
1 | 3 | 4 |
--------------------------------
2 | 5 | 6 |

最新更新