访问者模式就是在不改变数据结构的前提下,可以对数据结构中的每一个元素进行各种操作。
访问者适用于数据结构稳定的情况,它将数据结构和作用于数据结构的操作分离,使作用于数据结构的操作更容易的派生出新的操作,而数据结构就不容易发生变化。
我们就拿男人和女人在不同情况下的不同反应为例,先写一个最简单的面向对象代码。
public class SimpleAbstract {
public static void main(String[] args) {
ArrayList<person1> person1s=new ArrayList<>();
Man1 man1=new Man1();
man1.action="成功";
person1s.add(man1);
Women1 women1=new Women1();
women1.action="失败";
person1s.add(women1);
Man1 man2=new Man1();
man2.action="恋爱";
person1s.add(man2);
for (person1 p1:person1s){
p1.getResult();
}
}
}
abstract class person1 {
String action = "";
public abstract void getResult();
}
class Man1 extends person1 {
public void getResult() {
if (action == "成功")
System.out.println(this.getClass().getSimpleName() + action + "时,背后有一个伟大的女人");
else if(action=="失败")
System.out.println(this.getClass().getSimpleName()+action+"时,闷头喝酒,谁也不用劝");
else if (action=="恋爱")
System.out.println(this.getClass().getSimpleName()+action+"时,凡事不懂也装懂");
}
}
class Women1 extends person1{
public void getResult(){
if (action == "成功")
System.out.println(this.getClass().getSimpleName() + action + "时,背后大多有一个不成功的男人");
else if(action=="失败")
System.out.println(this.getClass().getSimpleName()+action+"时,眼泪汪汪,谁也劝不了");
else if (action=="恋爱")
System.out.println(this.getClass().getSimpleName()+action+"时,遇事懂也装不懂");
}
}
在男人和女人类中用多个if连用来判断情况,现在只写了3种状态,等状态多起来if语句就会显的过长,不太好,而且想增加新的状态的话,我们需要更改已有的方法,违反了封闭-开放原则。
下面我们用访问者模式,数据结构分为男人和女人,比较稳定,轻易不会在添加新的品质了。作用于数据库的操作为男人和女人的各种状态。
public class VisitorModel {
public static void main(String []args){
Structure structure=new Structure();
structure.attach(new Man());
structure.attach(new Woman());
success s=new success();
structure.display(s);
fail f=new fail();
structure.display(f);
love l=new love();
structure.display(l);
}
}
abstract class person2{
public abstract void getResult(State state);
}
class Man extends person2{
public void getResult(State state){
state.ManExpression(this);
}
}
class Woman extends person2{
public void getResult(State state){
state.WomanExpression(this);
}
}
class Structure{
ArrayList<person2> persons=new ArrayList<>();
public void attach(person2 person2){
persons.add(person2);
}
public void detach(person2 person2){
persons.remove(person2);
}
public void display(State state){
for(person2 p2:persons){
p2.getResult(state);
}
}
}
abstract class State{
public abstract void ManExpression(person2 person2);
public abstract void WomanExpression(person2 person2);
}
class success extends State{
public void ManExpression(person2 person2){
System.out.println(person2.getClass().getSimpleName()+this.getClass().getSimpleName()+"时,背后多半有一个伟大的女人");
}
public void WomanExpression(person2 person2){
System.out.println(person2.getClass().getSimpleName()+this.getClass().getSimpleName()+"时,背后大半有一个不成功的男人");
}
}
class fail extends State{
public void ManExpression(person2 person2){
System.out.println(person2.getClass().getSimpleName()+this.getClass().getSimpleName()+"时,闷头喝酒,谁也不用劝");
}
public void WomanExpression(person2 person2){
System.out.println(person2.getClass().getSimpleName()+this.getClass().getSimpleName()+"时,眼泪汪汪,谁也劝不了");
}
}
class love extends State{
public void ManExpression(person2 person2){
System.out.println(person2.getClass().getSimpleName()+this.getClass().getSimpleName()+"时,不懂装懂");
}
public void WomanExpression(person2 person2){
System.out.println(person2.getClass().getSimpleName()+this.getClass().getSimpleName()+"时,懂也装不懂");
}
}
在作用于男人和女人的状态操作类中分别定义好男人和女人的不同方法。而在男人和女人类的方法中只需要执行各自男人或女人的状态方法。然后在声明一个对象结构类,在其中定义一个list容易,便于对数据结构进行遍历操作。
这种类型的代码,想增加一些新的状态的话,只需在新的状态类中写好对应的男人和女人的方法就可以了。但想增加一种新类型的人的话,不仅要写好类本身中的方法,还要修改各个状态类增加对应的方法。
访问者模式就是将数据结构和操作分离,使增加新的操作变得容易,增加新的数据结构变得困难。