fbpx
维基百科

访问者模式

访问者模式是一种将算法与对象结构分离的软件设计模式

Visitor, UML class diagram.

这个模式的基本想法如下:首先我们拥有一个由许多对象构成的对象结构,这些对象的类都拥有一个accept方法用来接受访问者对象;访问者是一个接口,它拥有一个visit方法,这个方法对访问到的对象结构中不同类型的元素作出不同的反应;在对象结构的一次访问过程中,我们遍历整个对象结构,对每一个元素都实施accept方法,在每一个元素的accept方法中回调访问者的visit方法,从而使访问者得以处理对象结构的每一个元素。我们可以针对对象结构设计不同的实在的访问者类来完成不同的操作。

访问者模式使得我们可以在传统的单分派语言(如SmalltalkJavaC++)中模拟双分派技术。对于支持多分派的语言(如CLOS),访问者模式已经内置于语言特性之中了,从而不再重要。

Python的例子

""" Visitor pattern example. """ from abc import ABCMeta, abstractmethod NOT_IMPLEMENTED = "You should implement this." class CarElement: __metaclass__ = ABCMeta @abstractmethod def accept(self, visitor): raise NotImplementedError(NOT_IMPLEMENTED) class Body(CarElement): def accept(self, visitor): visitor.visitBody(self) class Engine(CarElement): def accept(self, visitor): visitor.visitEngine(self) class Wheel(CarElement): def __init__(self, name): self.name = name def accept(self, visitor): visitor.visitWheel(self) class Car(CarElement): def __init__(self): self.elements = [ Wheel("front left"), Wheel("front right"), Wheel("back left"), Wheel("back right"), Body(), Engine() ] def accept(self, visitor): for element in self.elements: element.accept(visitor) visitor.visitCar(self) class CarElementVisitor: __metaclass__ = ABCMeta @abstractmethod def visitBody(self, element): raise NotImplementedError(NOT_IMPLEMENTED) @abstractmethod def visitEngine(self, element): raise NotImplementedError(NOT_IMPLEMENTED) @abstractmethod def visitWheel(self, element): raise NotImplementedError(NOT_IMPLEMENTED) @abstractmethod def visitCar(self, element): raise NotImplementedError(NOT_IMPLEMENTED) class CarElementDoVisitor(CarElementVisitor): def visitBody(self, body): print("Moving my body.") def visitCar(self, car): print("Starting my car.") def visitWheel(self, wheel): print("Kicking my {} wheel.".format(wheel.name)) def visitEngine(self, engine): print("Starting my engine.") class CarElementPrintVisitor(CarElementVisitor): def visitBody(self, body): print("Visiting body.") def visitCar(self, car): print("Visiting car.") def visitWheel(self, wheel): print("Visiting {} wheel.".format(wheel.name)) def visitEngine(self, engine): print("Visiting engine.") car = Car() car.accept(CarElementPrintVisitor()) car.accept(CarElementDoVisitor()) 

Java的例子

 interface Visitor { void visit(Wheel wheel); void visit(Engine engine); void visit(Body body); void visit(Car car); } class Wheel { private String name; Wheel(String name) { this.name = name; } String getName() { return this.name; } void accept(Visitor visitor) { visitor.visit(this); } } class Engine { void accept(Visitor visitor) { visitor.visit(this); } } class Body { void accept(Visitor visitor) { visitor.visit(this); } } class Car { private Engine engine = new Engine(); private Body body = new Body(); private Wheel[] wheels = { new Wheel("front left"), new Wheel("front right"), new Wheel("back left") , new Wheel("back right") }; void accept(Visitor visitor) { visitor.visit(this); engine.accept(visitor); body.accept(visitor); for (int i = 0; i < wheels.length; ++ i) wheels[i].accept(visitor); } } class PrintVisitor implements Visitor { public void visit(Wheel wheel) { System.out.println("Visiting " + wheel.getName() + " wheel"); } public void visit(Engine engine) { System.out.println("Visiting engine"); } public void visit(Body body) { System.out.println("Visiting body"); } public void visit(Car car) { System.out.println("Visiting car"); } } public class VisitorDemo { static public void main(String[] args) { Car car = new Car(); Visitor visitor = new PrintVisitor(); car.accept(visitor); } } 

一个实际的例子

这个例子是Htmlparser计划(页面存档备份,存于互联网档案馆)里的一段示例。为获得一个Web页面的所有内容,采用如下的方式使用类 TextExtractingVisitor:

Parser parser = new Parser("http://pageIwantToParse.com[永久失效連結]"); TextExtractingVisitor visitor = new TextExtractingVisitor(); parser.visitAllNodesWith(visitor); System.out.println(visitor.getExtractedText()); 

参考条目


访问者模式, 本條目存在以下問題, 請協助改善本條目或在討論頁針對議題發表看法, 此條目需要編修, 以確保文法, 用詞, 语气, 格式, 標點等使用恰当, 2013年10月2日, 請按照校對指引, 幫助编辑這個條目, 幫助, 討論, 此條目需要擴充, 2013年10月2日, 请協助改善这篇條目, 更進一步的信息可能會在討論頁或扩充请求中找到, 请在擴充條目後將此模板移除, 此條目需要补充更多来源, 2013年10月2日, 请协助補充多方面可靠来源以改善这篇条目, 无法查证的内容可能會因為异议提出而移除, 致使用者,. 本條目存在以下問題 請協助改善本條目或在討論頁針對議題發表看法 此條目需要編修 以確保文法 用詞 语气 格式 標點等使用恰当 2013年10月2日 請按照校對指引 幫助编辑這個條目 幫助 討論 此條目需要擴充 2013年10月2日 请協助改善这篇條目 更進一步的信息可能會在討論頁或扩充请求中找到 请在擴充條目後將此模板移除 此條目需要补充更多来源 2013年10月2日 请协助補充多方面可靠来源以改善这篇条目 无法查证的内容可能會因為异议提出而移除 致使用者 请搜索一下条目的标题 来源搜索 访问者模式 网页 新闻 书籍 学术 图像 以检查网络上是否存在该主题的更多可靠来源 判定指引 访问者模式是一种将算法与对象结构分离的软件设计模式 Visitor UML class diagram 这个模式的基本想法如下 首先我们拥有一个由许多对象构成的对象结构 这些对象的类都拥有一个accept方法用来接受访问者对象 访问者是一个接口 它拥有一个visit方法 这个方法对访问到的对象结构中不同类型的元素作出不同的反应 在对象结构的一次访问过程中 我们遍历整个对象结构 对每一个元素都实施accept方法 在每一个元素的accept方法中回调访问者的visit方法 从而使访问者得以处理对象结构的每一个元素 我们可以针对对象结构设计不同的实在的访问者类来完成不同的操作 访问者模式使得我们可以在传统的单分派语言 如Smalltalk Java和C 中模拟双分派技术 对于支持多分派的语言 如CLOS 访问者模式已经内置于语言特性之中了 从而不再重要 目录 1 Python的例子 2 Java的例子 3 一个实际的例子 4 参考条目Python的例子 编辑 Visitor pattern example from abc import ABCMeta abstractmethod NOT IMPLEMENTED You should implement this class CarElement metaclass ABCMeta abstractmethod def accept self visitor raise NotImplementedError NOT IMPLEMENTED class Body CarElement def accept self visitor visitor visitBody self class Engine CarElement def accept self visitor visitor visitEngine self class Wheel CarElement def init self name self name name def accept self visitor visitor visitWheel self class Car CarElement def init self self elements Wheel front left Wheel front right Wheel back left Wheel back right Body Engine def accept self visitor for element in self elements element accept visitor visitor visitCar self class CarElementVisitor metaclass ABCMeta abstractmethod def visitBody self element raise NotImplementedError NOT IMPLEMENTED abstractmethod def visitEngine self element raise NotImplementedError NOT IMPLEMENTED abstractmethod def visitWheel self element raise NotImplementedError NOT IMPLEMENTED abstractmethod def visitCar self element raise NotImplementedError NOT IMPLEMENTED class CarElementDoVisitor CarElementVisitor def visitBody self body print Moving my body def visitCar self car print Starting my car def visitWheel self wheel print Kicking my wheel format wheel name def visitEngine self engine print Starting my engine class CarElementPrintVisitor CarElementVisitor def visitBody self body print Visiting body def visitCar self car print Visiting car def visitWheel self wheel print Visiting wheel format wheel name def visitEngine self engine print Visiting engine car Car car accept CarElementPrintVisitor car accept CarElementDoVisitor Java的例子 编辑interface Visitor void visit Wheel wheel void visit Engine engine void visit Body body void visit Car car class Wheel private String name Wheel String name this name name String getName return this name void accept Visitor visitor visitor visit this class Engine void accept Visitor visitor visitor visit this class Body void accept Visitor visitor visitor visit this class Car private Engine engine new Engine private Body body new Body private Wheel wheels new Wheel front left new Wheel front right new Wheel back left new Wheel back right void accept Visitor visitor visitor visit this engine accept visitor body accept visitor for int i 0 i lt wheels length i wheels i accept visitor class PrintVisitor implements Visitor public void visit Wheel wheel System out println Visiting wheel getName wheel public void visit Engine engine System out println Visiting engine public void visit Body body System out println Visiting body public void visit Car car System out println Visiting car public class VisitorDemo static public void main String args Car car new Car Visitor visitor new PrintVisitor car accept visitor 一个实际的例子 编辑这个例子是Htmlparser计划 页面存档备份 存于互联网档案馆 里的一段示例 为获得一个Web页面的所有内容 采用如下的方式使用类 TextExtractingVisitor Parser parser new Parser http pageIwantToParse com 永久失效連結 TextExtractingVisitor visitor new TextExtractingVisitor parser visitAllNodesWith visitor System out println visitor getExtractedText 参考条目 编辑软件设计模式 组合模式 取自 https zh wikipedia org w index php title 访问者模式 amp oldid 65669280, 维基百科,wiki,书籍,书籍,图书馆,

文章

,阅读,下载,免费,免费下载,mp3,视频,mp4,3gp, jpg,jpeg,gif,png,图片,音乐,歌曲,电影,书籍,游戏,游戏。