网站建设相关网站,商城网站的模块设计,wordpress去重复,在线建站意图#xff1a; 表示一个作用于某对象结构的各元素的操作。它使你可以再不改变各元素的类的前提下定义作用于这些元素的新操作。 动机#xff1a; 之前在学校的最后一个小项目就是做一个编译器#xff0c;当时使用的就是访问者模式。 在静态分析阶段#xff0c;将源程序表…意图 表示一个作用于某对象结构的各元素的操作。它使你可以再不改变各元素的类的前提下定义作用于这些元素的新操作。 动机 之前在学校的最后一个小项目就是做一个编译器当时使用的就是访问者模式。 在静态分析阶段将源程序表示为一个抽象语法树编译器需要在抽象语法树的基础上实施某些操作以进行静态语义分析。可能需要定义许多操作以进行类型检查、代码优化、流程分析、检查变量是否在使用前被赋值等等。 这个需求的特点是要求对不同的节点进行不同的处理。 常规设计方法不同的节点封装不同的操作。 缺点是节点类型过多将操作分散在各个节点类中会导致整个系统难以理解、维护和修改。增加新的操作要修改和重新编译所有的类。 改进节点类独立于作用于其上的操作。 1 将相关操作封装在一个独立的对象Visitor中并在遍历抽象语法树时将此对象传递给当前访问的元素。 2 当一个节点接受一个访问者时该元素向访问者发送一个包含自身类信息的请求。该请求同时也将该元素本身作为一个参数。 3 访问者将对该元素执行该操作。 适用性 在下列情况下使用Visitor模式 一个对象结构包含很多类对象 需要对其中的对象进行很多不同的并且不相关的操作 对象很少改变经常需要对其上的操作进行修改或新增 需要注意的一点是如果对象结果和接口经常改变那么会导致需要重定义所有访问者的接口会导致很大的代价。所以这种情况还是在对象类中定义操作比较好。 结构 协作 示例代码 背景假设你的电脑出现问题了 拿到售后那边检测售后告诉你必须拆机检测检测过程通过两个技术人员依次负责不同功能的检测。 分析本例中两个负责不同功能检测的技术人员就是Visitor而电脑的各个部件就是elements。 特点电脑的部件是固定的不会有太大的改变但是如果一种检测方式没有找出问题的话那么就需要增加检测项。符合访问者模式的特点。//visit.h#ifndef VISITOR_H
#define VISITOR_H#include iostream
#include string
#include vectorclass Element;
class CPU;
class VideoCard;
class MainBoard;/*------------------*/
class Visitor {
public:Visitor(std::string name) {visitorName name;}virtual void visitCPU( CPU* cpu ) {};virtual void visitVideoCard( VideoCard* videoCard ) {};virtual void visitMainBoard( MainBoard* mainBoard ) {};std::string getName() {return this-visitorName;};
private:std::string visitorName;
};class Element {
public:Element( std::string name ) {eleName name;}virtual void accept( Visitor* visitor ) {};virtual std::string getName() {return this-eleName;}
private:std::string eleName;
};/*----------- Elements -------------*/class CPU : public Element {
public:CPU(std::string name) : Element(name) {}void accept(Visitor* visitor) {visitor-visitCPU(this);}
};class VideoCard : public Element {
public:VideoCard(std::string name) : Element(name) {}void accept(Visitor* visitor) {visitor-visitVideoCard(this);}
};class MainBoard : public Element {
public:MainBoard(std::string name) : Element(name) {}void accept(Visitor* visitor) {visitor-visitMainBoard(this);}
};/*----------- ConcreteVisitor -------------*/class CircuitDetector : public Visitor {
public:CircuitDetector(std::string name) : Visitor(name) {}// checking cpuvoid visitCPU( CPU* cpu ) {std::cout Visitor::getName() is checking CPUs circuits.( cpu-getName()) std::endl;}// checking videoCardvoid visitVideoCard( VideoCard* videoCard ) {std::cout Visitor::getName() is checking VideoCards circuits.( videoCard-getName()) std::endl;}// checking mainboardvoid visitMainBoard( MainBoard* mainboard ) {std::cout Visitor::getName() is checking MainBoards circuits.( mainboard-getName() ) std::endl;}};class FunctionDetector : public Visitor {
public:FunctionDetector(std::string name) : Visitor(name) {}virtual void visitCPU( CPU* cpu ) {std::cout Visitor::getName() is check CPUs function.( cpu-getName() ) std::endl;}// checking videoCardvoid visitVideoCard( VideoCard* videoCard ) {std::cout Visitor::getName() is checking VideoCards function.( videoCard-getName() ) std::endl;}// checking mainboardvoid visitMainBoard( MainBoard* mainboard ) {std::cout Visitor::getName() is checking MainBoards function.( mainboard-getName() ) std::endl;}
};/*------------------------*/class Computer {
public:Computer(CPU* cpu,VideoCard* videocard,MainBoard* mainboard) {elementList.push_back(cpu);elementList.push_back(videocard);elementList.push_back(mainboard);};void Accept(Visitor* visitor) {for( std::vectorElement*::iterator i elementList.begin(); i ! elementList.end(); i ){(*i)-accept(visitor);}};
private:std::vectorElement* elementList;
};#endif // main.cpp#include visitor.hint main() {CPU* cpu new CPU(Intel CPU);VideoCard* videocard new VideoCard(XXX video card);MainBoard* mainboard new MainBoard(HUAWEI mainboard);Computer* myComputer new Computer(cpu, videocard, mainboard);CircuitDetector* Dan new CircuitDetector(CircuitDetector Dan);FunctionDetector* Tom new FunctionDetector(FunctionDetector Tom);std::cout \nStep 1: Dan is checking computers circuits. std::endl;myComputer-Accept(Dan);std::cout \nStep 2: Tom is checking computers functions. std::endl;myComputer-Accept(Tom);system(Pause);return 0;
}运行截图 参考资料 《设计模式:可复用面向对象软件的基础》转载于:https://www.cnblogs.com/suzhou/p/designpattern17visitor.html