cib*_*en1 0 java generics templates visitor
以下是使用泛型的访问者模式的java实现,一般是否有用?(我想是的).
它能以某种方式得到改善吗?使用匿名类轻松调用很重要.谢谢.
(使用示例):
Vector<Number> numbers = new Vector<Number>();
numbers.add(new Double(1.2));
numbers.add(new Float(-1.2));
numbers.add(new Double(4.8));
numbers.add(new Float(-3.4));
numbers.add(new Long(123456));
numbers.add(new Short("14"));
For.each(numbers, new Visitor<Number>() {
public void doIt(Double n) {
System.out.println("doIt() for double: " + n);
}
public void doIt(Float n) {
System.out.println("doIt() for float: " + n);
}
public void doIt(Number n) {
System.out.println("doIt() for Number: " + n);
}
});
Visitor<Number> visi = new Visitor<Number>() {
private StringBuffer all = new StringBuffer ();
public void doIt(Number n) {
System.out.println("doIt() for Number: " + n);
all.append(n.toString() + " ");
}
public Object getResult () {
return all;
}
};
For.each(numbers, visi);
System.out.println ("all -> " + visi.getResult());
Run Code Online (Sandbox Code Playgroud)
定义:
//............................................
abstract class Visitor<T> {
public void visit(T n) {
try {
this.getClass().getDeclaredMethod("doIt", n.getClass()).invoke(this, n);
} catch (Exception ex) {
doIt((T) n);
}
}
public void doIt(T n) {
System.out.println("doIt() for base " + n);
}
public Object getResult() {
return null;
}
} // class
//............................................
class For {
public static <T> void each (Collection<T> c, Visitor<T> f) {
for (T v : c) {
f.visit(v);
}
} // ()
} // class
Run Code Online (Sandbox Code Playgroud)
这不是访客模式.
访问者的特征在于,访问者具有accept(Visitor v)与访问者中的访问方法相互作用的方法,该方法将访问者作为参数并且针对不同类型的访问者进行过载,从而形成"双重调度"机制.
引自设计模式访客的"适用性"部分:
使用访客模式时
- 对象结构包含许多具有不同接口的对象类,并且您希望对依赖于其具体类的这些对象执行操作.
- 需要对对象结构中的对象执行许多不同且不相关的操作,并且您希望避免使用这些操作"污染"它们的类.访问者允许您通过在一个类中定义它们来保持相关操作.当许多应用程序共享对象结构时,使用Visitor将操作放在那些需要它们的应用程序中.
- 定义对象结构的类很少改变,但是你经常想要在结构上定义新的操作.更改对象结构类需要重新定义所有访问者的界面,这可能是昂贵的.如果对象结构类经常更改,那么在这些类中定义操作可能更好.
因此,这种模式用于处理多种类型对象上的类似操作.在您的示例中,您呼叫访问者的对象只能处理一种类型.
在你的答案中修改使用反射来处理多种类型(顺便说一句,这样做可以更好地作为对问题的编辑或作为一个单独的问题),你要避免accept(Visitor v)使用反射在被访问类中创建一个方法,这是在一定程度上实现了同一个目标,但有些尴尬.我仍然会拒绝将其称为访客的实施.
如果您在此处撰写的样式中的代码对您有用,请务必使用它,但请不要将其称为访问者.
这更像是一个策略模式或一个函数对象,如果你以反映它的方式重命名泛型类,它实际上是有用的,你的用法类似于函数式语言中列表处理的常见模式.
我可能会从问题的代码做的是重命名Visitor<T>到Operation<T>和你的命名visit(T t)到execute(T t)或apply(T t),一个思想Operation为Function没有返回值.事实上,我的确使用的方式类似于你正在做的事情,并使用类似的策略来使用通用Function<Domain, Range>对象进行集合"映射" .我不确定哪个模式名称实际适合它,但它不是访客.它为OO世界带来了功能列表理解风格,其中函数不是天生的一流对象.
| 归档时间: |
|
| 查看次数: |
4489 次 |
| 最近记录: |