您的位置:首页 > 其它

osg中的访问器模式

2008-04-03 15:18 141 查看
首先说一下visitor模式, 下面是一些大家之言:

1.Visitor模式是对在多个抽象的对象群的一种特殊处理,适合在这样一个场景:有一堆身份各异对象(通常是数据状态类),这些状态类有一些特征:被动的(数据都是被动的),需要等待外界来操作或推动。那么现在外界有一个动作来准备操作这些状态类了,但是走到面前,突然傻眼,分不清楚谁是谁啊?这些状态类可能属于不同类型的接口,怎么办?解决思路,当然把这些状态类再统一到一个接口下就可以操作了。当然,这时需要这些状态类做些修饰,有个“对外开放”的姿态,再实现一个统一接口Visitable,这个接口中提供的方法就更抽象:Accept()。其实Accept方法的具体实现是采取了Adapter模式,因为各个状态类都分属不同的接口,总不能为接受访问修改这些接口吧。

 2.visitor用多态去掉了这个type switch,并且遵循ocp, 用“容易添加新类”这个“你不需要的优势”来换取“容易添加新的方法”这个“你需要的优势”。

OSG中的NodeVisitor是对访问器(visitor)模式思想的具体实现。 从本质上说,NodeVisitor类遍历了一个场景图形并为每一个被访问节点调用特定的函数。

在OSG中的visitor最关键的两个函数是apply函数,该函数决定了遍历的方式,例如可以获得各个节点的属性,也可以修改节点的属性,这完全取决于apply函数的实现,用户可以创建新的继承于NodeVisitor的类,重写apply函数,apply函数的调用对用户是透明的,用户根本不用关心;另外一个就是accept函数,用户调用该函数可以关联访问器与要访问的对象。

以下并不想具体介绍OSG中的源代码,因为实在是太庞大了,下面只是OSG中的visitor的模型:

#include <iostream>
#include <string>
#include <vector>

class NodeVisitor;
class Node;
class Group;

class Node
{
public:
virtual const char* className() const { return "Node"; }
virtual void traverse(NodeVisitor& /*nv*/)	{}
virtual void accept(NodeVisitor &nv);
};

class NodeVisitor
{
public:
inline  void traverse(Node& node)	{ node.traverse(*this); }
virtual void apply(Node& node)		{ traverse(node); }
virtual void apply(Group& node)		{ apply( (Node&)node ); }
};

//Node::accept函数的定义必须位于NodeVisitor之后
void Node::accept(NodeVisitor& nv)
{	nv.apply(*this);	}

class Group : public Node
{
public:
typedef std::vector<Node*> NodeList;
virtual const char* className() const { return "Group"; }
~Group()
{/*...内存处理,篇幅有限*/}
void addChild(Node* p){_children.push_back(p);}
virtual void traverse(NodeVisitor& nv)
{
for(NodeList::iterator itr=_children.begin();
itr!=_children.end();
++itr)
{
(*itr)->accept(nv);
}
}
virtual void accept(NodeVisitor& nv)
{nv.apply(*this);}
private:
std::vector<Node*> _children;
};

//用户可以重写Visitor里面的apply函数实现某些特殊的功能;
class PrintName : public NodeVisitor
{
public:
PrintName()
: is_visit_child(true)
{}
virtual void apply(Node& node)
{
std::cout<<node.className()<<std::endl;

if(is_visit_child)
traverse(node);		//提示可以继续遍历其他的子节点
}

private:
bool is_visit_child;
};

int main()
{
PrintName pVisitor;

Node* pNode = new Node;
pNode->accept(pVisitor);		//接受遍历: Node
std::cout << "-----1-----" << std::endl;

Group* pGroup= new Group;
pGroup->accept(pVisitor);		//接受遍历: Group
std::cout << "-----2-----" << std::endl;

pGroup->addChild( pNode );
pGroup->addChild( new Group );
pGroup->accept( pVisitor );	//接受遍历: Group Node Group
std::cout << "-----3-----" << std::endl;

return 0;
}


下面是有关OSG中的visitor关系图:

 


- add 2013/7/31 dizuo 

OCP: open close principle 开-闭原则

访问器模式:通过继承方式增加新的接口,工厂模式:通过继承的方式实现虚构造函数!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息