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的模型:
下面是有关OSG中的visitor关系图:
- add 2013/7/31 dizuo
OCP: open close principle 开-闭原则
访问器模式:通过继承方式增加新的接口,工厂模式:通过继承的方式实现虚构造函数!
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 开-闭原则
访问器模式:通过继承方式增加新的接口,工厂模式:通过继承的方式实现虚构造函数!
相关文章推荐
- 文件读写&访问sdcard&文件操作模式
- 单例模式--确保一个类只有一个实例,并提供一个全局访问点。
- Silverlight通过TCP协议访问双工模式的WCF(Host在控制台)
- php的public、protected、private三种访问控制模式的区别
- Spring 资源访问剖析和策略模式应用
- 本人初学设计模式时写的一个支持多数据库的数据访问接口
- Asp.Net Core 2.0 之旅---数据访问仓储模式的事务管理
- 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【二】——使用Repository模式构建数据库访问层
- 单例模式在高并发情形下造成的访问覆盖问题
- PV对第三方存储的访问模式支持
- Objective-C如何自己实现一个基于数组下标的属性访问模式
- asp.net Web.config 在不同版本的IIS配置的IHttpHandler的访问路径,以及经典模式和集成模式不同的配置
- 设计模式(十三)-访问者模式(Visitor Pattern)——访问数据结构并处理数据
- window.showModalDialog模式窗口无法在子窗口访问解决办法
- HBase学习(一)hbase安装(单机模式)和javaapi客户端访问hbase例子
- CAS (6) —— Nginx代理模式下浏览器访问CAS服务器网络顺序图详解
- 启用始终脱机模式下提供对文件更快的访问权限
- 单例模式、package、instanceof及访问修饰符
- 用SERVICE LOCATOR 模式实现命名访问
- ubuntu配置svn及http模式访问