访问者模式

有点绕.因为用到了双分派技术.首先是将具体状态作为参数传给”男人”类完成第一次分派,然后”男人”类调用具体状态中的方法将自己作为参数传进去,完成第二次分派.
这个模式中,Person的继承者个数是固定的,需要扩展的只是Aspect类,因此可以使用访问者模式.如果实际中Person类不确定,则不能使用访问者模式.
访问者模式适用于数据结构相对稳定的系统.(比如这里的男人和女人,只有两类)
它把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由的演化.(对比这里就是,Man和Woman作为稳定的数据结构,而Success、Love等状态作为访问者,是对结构的操作嘛)

1
2
3
4
5
6
7
8
9
package visitor;

/**
* Created by hero on 17-2-21.
*/
public abstract class Person {
public abstract void getAttitude(Aspect aspect);
}

1
2
3
4
5
6
7
8
9
10
11
12
package visitor;

/**
* Created by hero on 17-2-21.
*/
public class Man extends Person{
@Override
public void getAttitude(Aspect aspect) {
aspect.getManAttitude(this);
}
}

1
2
3
4
5
6
7
8
9
10
11
12
package visitor;

/**
* Created by hero on 17-2-21.
*/
public class Woman extends Person {
@Override
public void getAttitude(Aspect aspect) {
aspect.getWomanAttitude(this);
}
}

1
2
3
4
5
6
7
8
9
10
package visitor;

/**
* Created by hero on 17-2-21.
*/
public abstract class Aspect {
public abstract void getManAttitude(Man man);
public abstract void getWomanAttitude(Woman woman);
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package visitor;

/**
* Created by hero on 17-2-21.
*/
public class Love extends Aspect {
@Override
public void getManAttitude(Man man) {
System.out.println("男人恋爱时,凡事不懂也要装懂");
}

@Override
public void getWomanAttitude(Woman woman) {
System.out.println("女人恋爱时,遇事懂也装不懂");
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package visitor;

/**
* Created by hero on 17-2-21.
*/
public class Success extends Aspect {
@Override
public void getManAttitude(Man man) {
System.out.println("男人成功时,背后有一个伟大的女人");
}

@Override
public void getWomanAttitude(Woman woman) {
System.out.println("女人成功时,背后有一个失败的男人");
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package visitor;

import java.util.LinkedList;
import java.util.List;

/**
* 对象结构
*/
public class ObjectStructure {
private List<Person> elements = new LinkedList<>();

public void attach(Person element) {
elements.add(element);
}

public void detach(Person element) {
elements.remove(element);
}

public void display(Aspect aspect) {
for (Person e : elements) {
e.getAttitude(aspect);
}
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package visitor;

/**
* Created by hero on 17-2-21.
*/
public class Main {
public static void main(String[] args) {
Man man = new Man();
Woman woman = new Woman();
Success success = new Success();
Love love = new Love();

ObjectStructure structure = new ObjectStructure();

structure.attach(man);
structure.attach(woman);

structure.display(success);
structure.display(love);
}
}