访问者模式是一种将数据操作与数据结构分离的设计模式,它的实现主要就是通过预先定义好调用的通路,在被访问的对象上定义accept方法,在访问者的对象上定义visit方法;然后在调用真正发生的时候,通过两次分发的技术,利用预先定义好的通路,回调到访问者具体的实现上。主要解决现已稳定的数据结构和易变的操作耦合问题,把数据结构和作用于结构上的操作解耦合,使得操作集合可相对自由地演化。如果所有数据结构一致,可以抽象出公共接口,则数据结构和操作皆可以自由扩展。
public interface Visitor {
public void visit(Subject sub);
}
#访问者 visit方法
public class MyVisitor implements Visitor {
@Override
public void visit(Subject sub) {
System.out.println("visit the subject:"+sub.getSubject());
}
}
#Subject类,accept方法,接受将要访问它的对象,getSubject()获取将要被访问的属性,
public interface Subject {
public void accept(Visitor visitor);
public String getSubject();
}
#数据结构
public class MySubject implements Subject {
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
@Override
public String getSubject() {
return "love";
}
}
public class Test {
public static void main(String[] args) {
Visitor visitor = new MyVisitor();
Subject sub = new MySubject();
sub.accept(visitor);
}
}
下面是我这边从网上找的一段示例代码,觉得还可以,借来用下:
//员工基类
public abstract class Staff {
public String name;
//员工kpi
public int kpi;
public Staff(String name) {
this.name = name;
kpi = new Random().nextInt(10);
}
//接收Visitor的访问
public abstract void accept(Visitor visitor);
}
//工程师
public class Engineer extends Staff {
public Engineer(String name) {
super(name);
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
//工程师这一年写的代码数量
public int getCodeLines(){
return new Random().nextInt(10*10000);
}
}
//经理类型
public class Manager extends Staff {
private int products; // 产品数量
public Manager(String name) {
super(name);
products = new Random().nextInt(10);
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
//一年内做的产品数量
public int getProducts(){
return products;
}
}
// 员工业务报表1类
public class BusinessReport {
List<Staff> mStaffs = new LinkedList<Staff>();
public BusinessReport() {
mStaffs.add(new Manager("米经理"));
mStaffs.add(new Engineer("工程师-jia"));
mStaffs.add(new Engineer("工程师-wei"));
mStaffs.add(new Engineer("工程师-wang"));
mStaffs.add(new Engineer("工程师-shi"));
}
/** * 为访问者展示报表 * @param visitor */
public void showReport(Visitor visitor){
for (Staff staff : mStaffs){
staff.accept(visitor);
}
}
}
//访问者接口
public interface Visitor {
//访问工程师类型
public void visit(Engineer engineer);
//访问经理类型
public void visit(Manager leader);
}
//CEO访问者,只关注业绩
public class CEOVisitor implements Visitor {
@Override
public void visit(Engineer engineer) {
System.out.println("工程师:" + engineer.name + ",KPI:" + engineer.kpi);
}
@Override
public void visit(Manager leader) {
System.out.println("经理:" + leader.name + ", KPI:" + leader.kpi + ",新产品数量:" + leader.getProducts());
}
}
public class CTOVisitor implements Visitor {
@Override
public void visit(Engineer engineer) {
System.out.println("工程师:"+engineer.name+",代码函数:"+engineer.getCodeLines());
}
@Override
public void visit(Manager leader) {
System.out.println("经理:"+leader.name+",产品数量:"+leader.getProducts());
}
}
//客户端代码
public class Client {
public static void main(String[] args){
//构建报表
BusinessReport report = new BusinessReport();
System.out.println("==========给CEO看的报表=========");
//设置访问者,这里是CEO
report.showReport(new CEOVisitor());
System.out.println("==========给CTO看的报表=========");
//注入另一个访问者CTO
report.showReport(new CTOVisitor());
}
}