访问者模式:修订间差异
外观
删除的内容 添加的内容
补救1个来源,并将0个来源标记为失效。) #IABot (v2.0.8 |
|||
(未显示10个用户的12个中间版本) | |||
第1行: | 第1行: | ||
{{multiple issues| |
|||
{{copyedit|time=2013-10-02T03:03:59+00:00}} |
|||
{{expand|time=2013-10-02T03:03:59+00:00}} |
|||
{{refimprove|time=2013-10-02T03:03:59+00:00}} |
|||
}} |
|||
[[File:Visitor UML class diagram.svg|thumb|400px|Visitor, [[UML]] class diagram.]] |
[[File:Visitor UML class diagram.svg|thumb|400px|Visitor, [[UML]] class diagram.]] |
||
第8行: | 第13行: | ||
== [[Python]]的例子 == |
== [[Python]]的例子 == |
||
< |
<syntaxhighlight lang="python"> |
||
""" |
|||
class Wheel: |
|||
Visitor pattern example. |
|||
def __init__(self,name): |
|||
""" |
|||
self.name = name |
|||
def accept(self,visitor): |
|||
from abc import ABCMeta, abstractmethod |
|||
visitor.visitWheel(self) |
|||
NOT_IMPLEMENTED = "You should implement this." |
|||
class Engine: |
|||
def accept(self,visitor): |
|||
class CarElement: |
|||
visitor.visitEngine(self) |
|||
__metaclass__ = ABCMeta |
|||
@abstractmethod |
|||
class Body: |
|||
def accept(self, visitor): |
|||
raise NotImplementedError(NOT_IMPLEMENTED) |
|||
class Body(CarElement): |
|||
def accept(self, visitor): |
|||
visitor.visitBody(self) |
|||
self.body = Body() |
|||
self.wheels = [ Wheel("front left"), Wheel("front right"), |
|||
class Engine(CarElement): |
|||
Wheel("back left") , Wheel("back right") ] |
|||
def accept(self, visitor): |
|||
visitor.visitEngine(self) |
|||
self.engine.accept( visitor ) |
|||
self.body.accept( visitor ) |
|||
class Wheel(CarElement): |
|||
for wheel in self.wheels: |
|||
def __init__(self, name): |
|||
wheel.accept( visitor ) |
|||
self.name = name |
|||
def accept(self, visitor): |
|||
class PrintVisitor: |
|||
visitor.visitWheel(self) |
|||
print "Visiting "+wheel.name+" wheel" |
|||
class Car(CarElement): |
|||
def visitEngine(self,engine): |
|||
def __init__(self): |
|||
print "Visiting engine" |
|||
self.elements = [ |
|||
Wheel("front left"), Wheel("front right"), |
|||
Wheel("back left"), Wheel("back right"), |
|||
def visitCar(self,car): |
|||
Body(), Engine() |
|||
] |
|||
car = Car() |
|||
def accept(self, visitor): |
|||
visitor = PrintVisitor() |
|||
for element in self.elements: |
|||
car.accept(visitor) |
|||
element.accept(visitor) |
|||
</source> |
|||
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()) |
|||
</syntaxhighlight> |
|||
== [[Java]]的例子 == |
== [[Java]]的例子 == |
||
< |
<syntaxhighlight lang="java"> |
||
interface Visitor { |
interface Visitor { |
||
void visit(Wheel wheel); |
void visit(Wheel wheel); |
||
第123行: | 第170行: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</source> |
|||
== 一个实际的例子 == |
== 一个实际的例子 == |
||
这个例子是[http://htmlparser.sourceforge.net/ Htmlparser计划]里的一段示例。为获得一个Web页面的所有内容,采用如下的方式使用类 TextExtractingVisitor: |
这个例子是[http://htmlparser.sourceforge.net/ Htmlparser计划]{{Wayback|url=http://htmlparser.sourceforge.net/ |date=20040715035442 }}里的一段示例。为获得一个Web页面的所有内容,采用如下的方式使用类 TextExtractingVisitor: |
||
Parser parser = new Parser("http://pageIwantToParse.com"); |
Parser parser = new Parser("http://pageIwantToParse.com{{dead link|date=2018年4月 |bot=InternetArchiveBot |fix-attempted=yes }}"); |
||
TextExtractingVisitor visitor = new TextExtractingVisitor(); |
TextExtractingVisitor visitor = new TextExtractingVisitor(); |
||
parser.visitAllNodesWith(visitor); |
parser.visitAllNodesWith(visitor); |
||
第137行: | 第184行: | ||
* [[组合模式]] |
* [[组合模式]] |
||
[[Category:软件设计模式]] |
|||
{{软件设计模式}} |
|||
[[fr:Visiteur (patron de conception)]] |
|||
[[Category:软件设计模式]] |
|||
[[gl:Visitor (patrón de deseño)]] |
2021年5月17日 (一) 20:09的最新版本
访问者模式是一种将算法与对象结构分离的软件设计模式。
这个模式的基本想法如下:首先我们拥有一个由许多对象构成的对象结构,这些对象的类都拥有一个accept方法用来接受访问者对象;访问者是一个接口,它拥有一个visit方法,这个方法对访问到的对象结构中不同类型的元素作出不同的反应;在对象结构的一次访问过程中,我们遍历整个对象结构,对每一个元素都实施accept方法,在每一个元素的accept方法中回调访问者的visit方法,从而使访问者得以处理对象结构的每一个元素。我们可以针对对象结构设计不同的实在的访问者类来完成不同的操作。
访问者模式使得我们可以在传统的单分派语言(如Smalltalk、Java和C++)中模拟双分派技术。对于支持多分派的语言(如CLOS),访问者模式已经内置于语言特性之中了,从而不再重要。
"""
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())
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());
参考条目
[编辑]