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

时间:2015-10-09 05:14:40

标签: oop design-patterns

我遇到了设计问题。我无法想出任何好的解决方案。这是问题陈述。

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

我怎么能解决这个问题?任何建议评论都会有很大的帮助。

2 个答案:

答案 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 |