[8] [行为变化] ( 2 ) 访问者 visitor
总结
-
为什么需要访问器模式?
在软件构建过程中,
有些需求的变化,
会导致类层次结构需要添加某些新的行为,
进而导致源代码的更改,
这违背了开闭原则.
![image]()
-
如何在不改源码的前提下,在运行时添加新行为,避免上述问题?
使用visitor模式
(将编译时扩展行为向后延迟,转化为运行时扩展行为)
-
GOF定义?
表示一个作用于某对象结构中的各元素的操作.
使得可以在不改变(稳定)各element类的前提下,
定义(扩展)作用于这些element的新操作(变化)
-
visitor的实现思路?
主要作用将数据结构和数据操作分离,
使操作集合可以独立于数据结构变化,
在不改变数据结构的前提下,
通过添加新的操作来扩展功能.
(添加新的Visitor就是添加新的操作)
-
使用visitor模式的严格前提?
定义Visitor的时候必须知道Element有几个子类.
如果不能确定Element子类的个数,
Visitor就没法稳定下来.
所以Visitor模式只适用于Element子类稳定的情况..
.
换一个具体的说法:
添加新的数据结构, 所有的访问者都要被修改.
因为Visitor类的方法的参数是Element,
Visitor依赖于Element,
修改Element的数据结构,
Visitor内对Element的操作也要改.
-
应用案例?
文档转换(用visitor模式遍历markdown文档的元素, 生成对应的html/pdf元素)
-
主要组件?
Element
ConcreteElement
Visitor
ConcreteVisitor
java例子
重构前
package v32_visitor.java;
interface Shape {
void draw();
void resize();
}
class Circle implements Shape {
public void draw() {
System.out.println("Drawing a circle");
}
public void resize() {
System.out.println("Resizing a circle");
}
}
class Rectangle implements Shape {
public void draw() {
System.out.println("Drawing a rectangle");
}
public void resize() {
System.out.println("Resizing a rectangle");
}
}
public class ShapeMain1 {
public static void main(String[] args) {
Shape circle = new Circle();
Shape rectangle = new Rectangle();
circle.draw();
rectangle.draw();
circle.resize();
rectangle.resize();
}
}
重构后
package v32_visitor.java;
interface Shape {
void accept(Visitor visitor);
}
class Circle implements Shape {
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
class Rectangle implements Shape {
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
interface Visitor {
void visit(Circle circle);
void visit(Rectangle rectangle);
}
class DrawVisitor implements Visitor {
public void visit(Circle circle) {
System.out.println("Drawing a circle");
}
public void visit(Rectangle rectangle) {
System.out.println("Drawing a rectangle");
}
}
class ResizeVisitor implements Visitor {
public void visit(Circle circle) {
System.out.println("Resizing a circle");
}
public void visit(Rectangle rectangle) {
System.out.println("Resizing a rectangle");
}
}
public class ShapeMain2 {
public static void main(String[] args) {
Shape circle = new Circle();
Shape rectangle = new Rectangle();
Visitor drawVisitor = new DrawVisitor();
Visitor resizeVisitor = new ResizeVisitor();
circle.accept(drawVisitor);
rectangle.accept(drawVisitor);
circle.accept(resizeVisitor);
rectangle.accept(resizeVisitor);
}
}


c++例子
重构前
#include <iostream>
using namespace std;
class Visitor;
// 接口
class Element {
public:
virtual void Func1() = 0;
virtual void Func2(int data) = 0;
virtual void Func3(int data) = 0;
//...
virtual ~Element() {}
};
class ElementA : public Element {
public:
void Func1() override {
//...
}
void Func2(int data) override {
//...
}
};
class ElementB : public Element {
public:
void Func1() override {
//***
}
void Func2(int data) override {
//***
}
};
重构后
#include <iostream>
using namespace std;
class Visitor;
class Element {
public:
virtual void accept(Visitor& visitor) = 0; //第一次多态辨析
virtual ~Element() {}
};
class ElementA : public Element {
public:
void accept(Visitor& visitor) override { visitor.visitElementA(*this); }
};
class ElementB : public Element {
public:
void accept(Visitor& visitor) override {
visitor.visitElementB(*this); //第二次多态辨析
}
};
class Visitor {
public:
virtual void visitElementA(ElementA& element) = 0;
virtual void visitElementB(ElementB& element) = 0;
virtual ~Visitor() {}
};
//==================================
//扩展1
class Visitor1 : public Visitor {
public:
void visitElementA(ElementA& element) override {
cout << "Visitor1 is processing ElementA" << endl;
}
void visitElementB(ElementB& element) override {
cout << "Visitor1 is processing ElementB" << endl;
}
};
//扩展2
class Visitor2 : public Visitor {
public:
void visitElementA(ElementA& element) override {
cout << "Visitor2 is processing ElementA" << endl;
}
void visitElementB(ElementB& element) override {
cout << "Visitor2 is processing ElementB" << endl;
}
};
int main() {
Visitor2 visitor;
ElementB elementB;
elementB.accept(visitor); // double dispatch
ElementA elementA;
elementA.accept(visitor);
return 0;
}



浙公网安备 33010602011771号