-- 访问者(Visitor)模式 元素的执行算法可以随着访问者改变而改变。根据模式,元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作。
总的来说就是:不同的访问者 -> 访问同一个元素 -> 产生不同的结果
老师(访客) -> 访问课室(元素) -> 教书
学生(访客) -> 访问课室(元素) -> 上课 (下面会有实际栗子)
一、使用场景
在软件系统中,行为请求者与行为实现者通常是一种紧耦合的关系,但某些场合,比如需要对行为进行记录、撤销或重做、事务等处理时,这种无法抵御变化的紧耦合的设计就不太合适。
二、模式结构
引用官方结构图:
组成(角色) | 作用 |
---|---|
Element (被访问的抽象元素) | 提供接收accpet(Visitor visitor)的方法 |
ConcreteElement (被访问的具体元素) | 实现具体元素 |
Visitor (抽象访问者) | 提供访问 具体元素 的抽象方法visit(ConcreteElement concreteElement1) |
ConcreteVisitor (具体访问者) | 实现访问者具体行为 |
二、优缺点
优点:
- 降低了耦合度。
- 对于访问者(Visitor)来说符合开闭原则,但如果要增加新的element,就会牵一发而动全身
缺点:
扫描二维码关注公众号,回复:
2810670 查看本文章
- 系统复杂性提高
三、栗子
1、被访问的抽象元素
- 提供接收accpet(Visitor visitor)的方法
package com.behavior.visitor;
/**
* @description: 元素
* @author: ziHeng
**/
public interface Element {
void accept(Visitor visitor);
}
2、ConcreteElement (被访问的具体元素)
(1)、课室
package com.behavior.visitor;
import lombok.Data;
/**
* @description: 课室
* @author: ziHeng
* @create: 2018-08-16 15:10
**/
@Data
public class Classroom implements Element {
String name;
public Classroom(String name) {
this.name = name;
}
@Override
public void accept(Visitor visitor) {
visitor.visitClassroom(this);
}
}
(2)、家庭
package com.behavior.visitor;
import lombok.Data;
/**
* @description: 家庭
* @author: ziHeng
* @create: 2018-08-16 16:41
**/
@Data
public class Family implements Element {
private String name;
public Family(String name) {
this.name = name;
}
@Override
public void accept(Visitor visitor) {
visitor.visitFamily(this);
}
}
3、Visitor 抽象访问者
-- 提供访问 每个具体元素 的抽象方法visit(ConcreteElement concreteElement1)
package com.behavior.visitor;
/**
* @description: 访问者抽象类
* @author: ziHeng
**/
public interface Visitor {
void visitClassroom(Classroom classroom);
void visitFamily(Family family);
}
4、ConcreteVisitor 具体访问者
(1)、学生
package com.behavior.visitor;
/**
* @description: 学生
* @author: ziHeng
* @create: 2018-08-16 15:53
**/
public class Student implements Visitor {
@Override
public void visitClassroom(Classroom classroom) {
System.out.println("学生在"+classroom.getName()+"上课");
}
@Override
public void visitFamily(Family family) {
System.out.println("学生在"+family.getName()+"当孩子");
}
}
(2)、老师
package com.behavior.visitor;
/**
* @description: 老师
* @author: ziHeng
* @create: 2018-08-16 15:53
**/
public class Teacher implements Visitor {
@Override
public void visitClassroom(Classroom classroom) {
System.out.println("老师在"+classroom.getName()+"教书");
}
@Override
public void visitFamily(Family family) {
System.out.println("老师在"+family.getName()+"当家长");
}
}
调用Test类:
package com.behavior.visitor;
/**
* @description: 访问者模式测试
* @author: ziHeng
* @create: 2018-08-16 15:59
**/
public class VisitorTest {
public static void main(String[] args) {
//初始化访问者visitor
Visitor teacher = new Teacher();
Visitor student = new Student();
//初始化被访问元素Element
Element classroom = new Classroom("课室");
Element family = new Family("家");
//访问者 访问元素
classroom.accept(teacher);
classroom.accept(student);
family.accept(teacher);
family.accept(student);
}
}
控制台结果: