Visitor模式的简单实现

[size=x-large]1.描述[/size]
一个集合中有同一种类型的数据,他们或者继承同一个父类,或者实现了同一个接口,但是他们各自的属性和方法有时却存在着差异,而这些数据一旦被添加进一些集合以后,他们的差异性就被一般化了,若需要再次取得这些具有“个性”的类的话,则要做大量如下的工作:

for(A a : collection){
if(a instance of B){
//.....
}else if(a instance of C){
//.....
}else ....
}

这样的代码就显得异常的繁琐,Visitor模式实际上就是在做与if else 相同的工作,但是他的代码更加飘逸一点。

[size=x-large]2.接口定义[/size]
两个主要接口:
~Visitor

public interface Visitor {

public void visit(StringElement s);

public void visit(IntElement n);

public void visit(DoubleElement d);

}

Visitor定义了不同类型的对象的访问方法


~Visitable

public interface Visitable {

public void accept(Visitor visitor);

}

Visitable定义的是被访问者接受访问者(也就是实现了visitor)访问的方法,如果实现visitable的对象accept了一个visitor对象,那么visitable就会调用visitor中相应的visit的方法(通过函数重载来实现),做到对visitable内所有可被访问的元素(同样也是实现了visitable)的遍历。(这话说的.....有点绕了...)

[size=x-large]3.具体实现类的函数定义如下:[/size]
三个实现了visitable接口的元素类:

public class IntElement implements Visitable{

private int value = 1;

public int getValue(){
return this.value;
}

public void accept(Visitor visitor) {
visitor.visit(this);
}

}

public class DoubleElement implements Visitable{

private double value = 1.1;

public double getValue(){
return this.value;
}

public void accept(Visitor visitor) {
visitor.visit(this);
}

}




public class StringElement implements Visitable{

private String value = "I'm String";

public String getValue(){
return this.value;
}

public void accept(Visitor visitor) {
visitor.visit(this);
}
}


同样是实现了visitable的集合类,visitor对象被这个集合类accept后,visitor便可以以各自的方法来访问这个集合中那些有“个性”的元素了

public class Elements implements Visitable{


private Collection<Visitable> col = new ArrayList();

public void addElement(Visitable v){
col.add(v);
}

public void accept(Visitor visitor) {
for(Visitable v : col){
v.accept(visitor);
}
}
}


主函数

public static void main(String args[]){
Elements es = new Elements();
es.addElement(new StringElement());
es.addElement(new IntElement());
es.addElement(new DoubleElement());
MyVisitor mv = new MyVisitor();
es.accept(mv);
}


运行结果:

element.StringElement:I'm String
element.IntElement:1
element.DoubleElement:1.1


先传个uml图上来,画得有点难看而且又点不规范,但是大概的模型就是这样的

[img]http://dl.iteye.com/upload/attachment/454090/88f370a2-7494-35c6-8da0-95cfc21cecf3.jpg[/img]

[size=x-large]4.写在后面:[/size]
刚开始接触到visitor模式时,的确有点不懂,后来是用到dom4j的时候,在解析xml文件时,发现dom4j对其提供的visitor模式支持非常好用,只需要创建一个visitor了实现类,给它几个筛选条件,我就能从一个Element中获得我想要的节点信息了,这是才对visitor模式有了一个大概的了解。不懂没关系,敲一敲就会明白的。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个访问者模式简单示例代码,该代码模拟了对不同类型的元素进行访问和处理的过程: ```java // 定义元素接口 interface Element { void accept(Visitor visitor); } // 定义具体元素类A class ElementA implements Element { @Override public void accept(Visitor visitor) { visitor.visit(this); } public void operationA() { System.out.println("执行元素A的操作"); } } // 定义具体元素类B class ElementB implements Element { @Override public void accept(Visitor visitor) { visitor.visit(this); } public void operationB() { System.out.println("执行元素B的操作"); } } // 定义访问者接口 interface Visitor { void visit(ElementA element); void visit(ElementB element); } // 定义具体访问者类 class ConcreteVisitor implements Visitor { @Override public void visit(ElementA element) { element.operationA(); } @Override public void visit(ElementB element) { element.operationB(); } } // 定义对象结构类 class ObjectStructure { private List<Element> elements = new ArrayList<>(); public void add(Element element) { elements.add(element); } public void remove(Element element) { elements.remove(element); } public void accept(Visitor visitor) { for (Element element : elements) { element.accept(visitor); } } } // 主函数 public class Main { public static void main(String[] args) { ElementA elementA = new ElementA(); ElementB elementB = new ElementB(); ObjectStructure objectStructure = new ObjectStructure(); objectStructure.add(elementA); objectStructure.add(elementB); Visitor visitor = new ConcreteVisitor(); objectStructure.accept(visitor); } } ``` 在该示例代码中,元素接口 `Element` 定义了一个 `accept` 方法,该方法用于接受一个访问者对象,并调用该访问者的 `visit` 方法。各个具体元素类实现了 `Element` 接口,并在 `accept` 方法中调用了访问者的 `visit` 方法。 访问者接口 `Visitor` 定义了多个 `visit` 方法,每个 `visit` 方法接受一个具体元素对象作为参数,用于访问该具体元素对象并对其进行处理。各个具体访问者类实现了 `Visitor` 接口,并实现了各自的 `visit` 方法。 对象结构类 `ObjectStructure` 维护了一个元素列表,并提供了 `add`、`remove` 和 `accept` 方法。`accept` 方法接受一个访问者对象,并遍历元素列表,对每个元素调用其 `accept` 方法,从而触发访问者的 `visit` 方法。 在主函数中,创建了两个具体元素对象 `elementA` 和 `elementB`,并将它们添加到 `ObjectStructure` 对象中。然后创建了一个具体访问者对象 `visitor`,并将其传递给 `ObjectStructure` 对象的 `accept` 方法,从而触发对每个元素的访问和处理。最终输出了元素A和元素B的操作结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值