我遇到了设计问题。我无法想出任何好的解决方案。这是问题陈述。
我有一套设备,每个设备都有一些共同的属性和行为。每个设备可以包含1个或多于一个与其连接的其他类型的设备。例如:如果有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.
我怎么能解决这个问题?任何建议评论都会有很大的帮助。
答案 0 :(得分:3)
这听起来像Visitor pattern的情况。您让访问者访问A
的每个孩子。对于每个孩子,它将再次访问所有孩子,依此类推。
当访问者遍历树时,您将收集有关每个节点的数据。在这种情况下,您可以根据需要直接以XML格式收集数据。
访问者模式适用于异构数据类型,但是当某些节点具有共同结构时也可以。
答案 1 :(得分:1)
访问者模式是执行操作的更好方法,其中所有父类和子类都应被接受为输入,其行为由对象类型决定。
以下是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 |