访问者模式:表示一个作用与某对象结构中的各元素操作,可以使在不改变各元素类的前提下定义这些元素的新操作
优点:可以将数据操作和数据结构分离
实现:人类在生理上分两种性别,男和女,这两种性别面对不同的行为,大多数会形成两种截然不同的反应。
1、个体类(数据结构)
/**
* 抽象个体
*/
public abstract class Person {
/**
* 针对行为作出的反应
*/
public abstract void doAction(Action action);
}
/**
* 男人
*/
public class ManPerson extends Person{
public void doAction(Action action){
action.manAction(this);
}
}
/**
* 女人
*/
public class WoManPerson extends Person{
public void doAction(Action action){
action.woManAction(this);
}
}
2、行为类(数据操作)
/**
* 抽象行为
*/
public abstract class Action {
/**
* 男人行为
*/
public abstract void manAction(ManPerson person);
/**
* 女人行为
*/
public abstract void woManAction(WoManPerson person);
}
/**
* 成功
*/
public class Success extends Action{
/**
* 男人行为
*/
public void manAction(ManPerson person){
System.out.println("男人成功背后,大多拥有一个伟大的女人");
}
/**
* 女人行为
*/
public void woManAction(WoManPerson person){
System.out.println("女人成功背后,大多拥有一个不成功的男人");
}
}
/**
* 失恋
*/
public class Lovelorn extends Action{
/**
* 男人行为
*/
public void manAction(ManPerson person){
System.out.println("男人失恋,大多闷头喝酒,谁也不用劝");
}
/**
* 女人行为
*/
public void woManAction(WoManPerson person){
System.out.println("女人失恋,大多泪眼汪汪,谁劝也不好使");
}
}
3、对象结构类(批量处理)
/**
* 对象结构类
*/
public class ObjectStructure {
List<Person> list = new ArrayList<>();
public void add(Person person){
list.add(person);
}
public void remove(Person person){
list.remove(person);
}
public void structure(Action action){
list.forEach(person -> {
person.doAction(action);
});
}
}
4、测试类
/**
* 测试访问者模式
*/
public class TestVisitor {
public static void main(String [] args){
ManPerson manPerson = new ManPerson();
WoManPerson woManPerson = new WoManPerson();
ObjectStructure objectStructure = new ObjectStructure();
objectStructure.add(manPerson);
objectStructure.add(woManPerson);
Action success = new Success();
Action lovelorn = new Lovelorn();
objectStructure.structure(success);
objectStructure.structure(lovelorn);
}
}
测试结果:
访问者模式通常的使用场景:
1、对象结构毕竟稳定,但是通常要对对象结构定义新的操作(譬如人类性别生理上分为男女两种,这个对象结构是固定的,但是人类的行为是千千万万)
2、需要对对象结构进行很多不同,并且不相关的操作,而需要避免这些操作污染这些类的对象,也不希望增加操作时修改这些类