定义
封装某些作用于某种数据结构中各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作
角色
抽象访问者(Visitor):声明访问者可以访问哪些元素
访问者:它决定访问者访问到一个类后该干什么,要做什么事情
抽象元素类(Element):声明接受哪一类访问者访问;它一般分为两个逻辑,一个是本身的业务,另一个是允许接收哪类访问者访问
元素类:实现抽象元素类
结构对象(Object Structure):一个接口容器
优点
- 符合单一职责原则:元素类封装在访问者中的操作一定是与元素本身关系不大且是易变的操作,当需求变化时, 不改变元素类本身,即可实现扩展
- 扩展性良好:元素可以通过接受不同的访问者来实现对不同操作的扩展
缺点
- 增加元素比较麻烦,每增加一个元素都要修改访问者类
适用场景
- 一个对象中存在一些与该对象不相干或关系较弱的操作,可用访问者模式把这些操作封装到访问者中
- 一些对象存在相似操作,为了避免出现大量重复的代码,也可以将重复操作封装到访问者中
- 由于新增元素比较困难,因此访问者模式比较适合对已有功能的重构
- 对象结构的类很少改变,但又经常需要在此结构上定义新的操作时
类图
package com.vapy.behavior.Visitor;
/**
*
* @author vapy
*
*/
public abstract class Element {
public abstract void accept(IVisitor visitor);
public abstract void doSomething();
}
package com.vapy.behavior.Visitor;
/**
*
* @author vapy
*
*/
public class Dancer extends Element {
@Override
public void accept(IVisitor visitor) {
visitor.visit(this);
}
@Override
public void doSomething() {
System.out.println("dance");
}
}
package com.vapy.behavior.Visitor;
/**
*
* @author vapy
*
*/
public class Singer extends Element {
@Override
public void accept(IVisitor visitor) {
visitor.visit(this);
}
@Override
public void doSomething() {
System.out.println("sing");
}
}
package com.vapy.behavior.Visitor;
/**
*
* @author vapy
*
*/
public interface IVisitor {
public void visit(Dancer dancer);
public void visit(Singer singer);
}
package com.vapy.behavior.Visitor;
/**
*
* @author vapy
*
*/
public class Visitor implements IVisitor {
@Override
public void visit(Dancer dancer) {
dancer.doSomething();
}
@Override
public void visit(Singer singer) {
singer.doSomething();
}
}
package com.vapy.behavior.Visitor;
/**
*
* @author vapy
*
*/
import java.util.ArrayList;
import java.util.List;
public class ObjectStruture {
public static List<Element> getList() {
List<Element> list = new ArrayList<Element>();
list.add(new Dancer());
list.add(new Dancer());
list.add(new Dancer());
list.add(new Singer());
return list;
}
}
package com.vapy.behavior.Visitor;
/**
*
* @author vapy
*
*/
import java.util.List;
public class Client {
public static void main(String[] args) {
List<Element> list = ObjectStruture.getList();
IVisitor visitor = new Visitor();
for(Element e : list) {
e.accept(visitor);
}
}
}
本文代码可在github查看:点击此处