2015-10-09 53 views
3

我困住了设计问题。我无法想出任何好的解决方案。这是问题陈述。设计类:每个类封装其他相关类的对象

我有一套设备,每个设备都有一些共同的属性和行为。每个设备可能包含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

那是什么,我想,当我开始做这个工作的......但我认为可以有更好的方式来解决这个问题 – HadeS

回答

3

这听起来像是Visitor pattern的情况。你让游客拜访A的每个孩子。对于每个孩子,它会再次访问所有的孩子,等等。

当访问者遍历树时,您收集有关每个节点的数据。在这种情况下,您可以直接以XML格式收集数据。

Visitor模式适用于异构数据类型,但当某些节点具有公共结构时也可以。

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 |