这是我的最后一篇关于java设计模式的博客,这是第23种模式。 对于访问者模式,就是通过调用不同的访问者的相同方法来完成对实现了相同接口的不同事物的访问,已达到显示不同结果的需要。
在这种模式中,可以说就分为两部分即可:访问者和被访问者。
访问者部分:
1. 要实现一个有着共同方法的但是实现不同的一个访问者接口 2. 实现此访问者接口的各种实现类,实现方法来访问不同的被访问者
被访问者部分:
1. 要实现一个有着共同方法的但是实现不同的一个被访问者接口 2. 实现此被访问者接口的多个实现类 3. 创建一个可以让访问者一次可以访问多个事物的类,其中可以通过集合遍历来实现
网络上的专业解释:
此模式中,使用了一个访问者类,它改变了元素的执行算法,元素的执行算法随着访问者的变化而变化,这样访问对象就可以处理元素对象上的操作。
实例:用此模式实现不同访问者完成对电脑不同部分的访问。
以下是我所画的类图:
以下是代码: 1.新建一个电脑一部分的接口
interface ComputerPart{
public void operate(Visitor visitor);
public String doAction();
}
2.创建电脑一部分接口的三个实现类(键盘,鼠标,主机)
public class Keyboard implements ComputerPart
{
@Override
public void operate(Visitor visitor)
{
visitor.visit(this);
}
@Override
public String doAction()
{
return "it is keyboard...";
}
}
public class Mouse implements ComputerPart
{
@Override
public void operate(Visitor visitor)
{
visitor.visit(this);
}
@Override
public String doAction()
{
return "it is mouse...";
}
}
public class Host implements ComputerPart
{
@Override
public void operate(Visitor visitor)
{
visitor.visit(this);
}
@Override
public String doAction()
{
return "it is host...";
}
}
3.创建电脑的整体类(可以使访问者访问电脑的好多部分)
public class Computer
{
private static final List<ComputerPart> cps=new ArrayList<ComputerPart>();
public void doAction(Visitor visitor){
for(ComputerPart item:cps){
item.operate(visitor);
}
}
public void addElements(ComputerPart cp){
cps.add(cp);
}
}
4.新建访问者接口
interface Visitor
{
void visit(ComputerPart cp);
void visit(Computer computer);
}
5.创建访问者接口的实现类,是可以产生多个访问者对象
public class Visitor_1 implements Visitor
{
@Override
public void visit(ComputerPart cp)
{
System.out.println("i am visitor_1,i visite "+cp.doAction());
}
@Override
public void visit(Computer computer)
{
System.out.println("i am visitor_1,i visite all computerPart...");
computer.doAction(this);
}
}
public class Visitor_2 implements Visitor
{
@Override
public void visit(ComputerPart cp)
{
System.out.println("i am visitor_2,i visite "+cp.doAction());
}
@Override
public void visit(Computer computer)
{
System.out.println("i am visitor_2,i visite all computerPart...");
computer.doAction(this);
}
}
6.创建测试类,测试不同的访问者对电脑部分和整体电脑的不同访问结果
public class Test
{
public static void main(String[] args)
{
//访问者1电脑的某一部分
Visitor v1=new Visitor_1();
v1.visit(new Keyboard());
v1.visit(new Mouse());
v1.visit(new Host());
//新建访问者2对象
Visitor v2=new Visitor_2();
//新建电脑类,可向其中添加各种电脑部分
Computer computer=new Computer();
computer.addElements(new Keyboard());
computer.addElements(new Mouse());
computer.addElements(new Host());
//访问整个电脑
v2.visit(computer);
}
}
7.后台运行
i am visitor_1,i visite it is keyboard...
i am visitor_1,i visite it is mouse...
i am visitor_1,i visite it is host...
i am visitor_2,i visite all computerPart...
i am visitor_2,i visite it is keyboard...
i am visitor_2,i visite it is mouse...
i am visitor_2,i visite it is host...
此模式的优点:
1.扩展方便,要添加类只需实现其中的接口即可。
2.访问者类中有且只有一个改变的原因,也就是被访问者的实现类,使访问者中的功能都比较单一,所以这 符合类的单一职责原则。
3.在这模式中,数据结构都放到了访问者部分,各种行为和实现结果都放到了被访问者部分,所以实现了数据结构和行为的分离。
缺点:
1.对于添加具体类中的元素比较麻烦,在访问者和被访问者中的代码都要修改。
2.被访问者中的实现方法和元素都会公开给访问者,这样的话就使这两者耦合度提高,违反了”迪米特原则”。