Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 避免使用番石榴或其他lib的访客模式?_Java_Guava_Visitor Pattern - Fatal编程技术网

Java 避免使用番石榴或其他lib的访客模式?

Java 避免使用番石榴或其他lib的访客模式?,java,guava,visitor-pattern,Java,Guava,Visitor Pattern,在某些情况下,访问者模式会产生不必要的复杂性和样板(许多accept方法),在我看来,完全的泛化是不可能的(accept()方法也返回值)。因此,我认为在我的情况下,还有另一种解决方案 当然,我不想为block创建很多if-else实例,我想找到一种聪明的方法来匹配特定类型(例如列表中的类型)和方法 例如,guava在its中有类似的功能,可以将特定类型的事件与@Subscribe注释的方法相匹配,因此我正在寻找一个类似的库,使这在一般情况下成为可能。 这里有一个例子,我想要类似的东西: 神奇

在某些情况下,访问者模式会产生不必要的复杂性和样板(许多accept方法),在我看来,完全的泛化是不可能的(accept()方法也返回值)。因此,我认为在我的情况下,还有另一种解决方案

当然,我不想为block创建很多if-else实例,我想找到一种聪明的方法来匹配特定类型(例如列表中的类型)和方法

例如,guava在its中有类似的功能,可以将特定类型的事件与@Subscribe注释的方法相匹配,因此我正在寻找一个类似的库,使这在一般情况下成为可能。
这里有一个例子,我想要类似的东西:

神奇的界面:

/**  @param <R> - return type  * @param <I> - element super type */
public interface MagicDoubleDispatch<R, I>{
    R dispatch(I element);
}
/**@param-返回类型*@param-元素超类型*/
公共接口MagicDoubleDispatch{
R调度(一要素);
}
我的“访问者”实现(应自动调用适当的方法)

公共类事件格式化程序扩展MagicDoubleDispatchImpl{
专用字符串格式(AddedEmployeeEvent事件){
返回String.format(“添加的新员工:%s,id为%s”,event.name,event.employeeId);
}
私有字符串格式(DeletedEmployeeEvent事件){
返回String.format(“已删除的员工:(%s)%s(此操作无法撤消!)”,event.employeeId,event.name);
}
专用字符串格式(AddedTimeCardEvent事件){
返回字符串.format(“已将%s的时间卡添加到%s”、event.date、event.employeeName);
}
}
我希望将此作为一个库(例如):

公共抽象类MagicDoubleDispatchImpl实现MagicDoubleDispatch{
//我想要这个…可能使用反射作为事件总线,我不在乎。。
}
客户端代码:

private EventFormatter eventFormatter = new EventFormatter();

public List<String> toStringList(List<Event> events) {
    return events.stream()
        .map(it -> eventFormatter.dispatch(it))
        .collect(Collectors.toList());
}
private EventFormatter EventFormatter=new EventFormatter();
公共列表到字符串(列出事件){
returnevents.stream()
.map(it->eventFormatter.dispatch(it))
.collect(Collectors.toList());
}
不确定“accept()方法还返回值”是什么意思,但无论如何,在代码生成器的帮助下,访问者模式可以非常轻量级:看一看-它提供了一种模式匹配语法,可以使代码非常可读


此外,没有任何其他技术/库能够提供像访问者模式那样多的类型安全性。

您可以制作一个映射,将类扩展事件作为键,以及将事件转换为字符串的函数

Map<Class<T extends Event>,Function<T,String>>
Map
如果您想要一些新奇的东西,您可以使用注释并基于这些注释创建注册表(使用spring很容易),但基本上最终结果是一样的

EventFormatter根据给定事件的类型在映射中查找该事件的格式化程序,并应用相应的函数。 如果您在事件类和格式化程序之间有一个1对1的映射,那么应该可以


如果您需要在给定类型没有格式化程序的情况下回退到父类,这会有点烦人,但可行。

为什么不使用Guava?我也是出于同样的原因写的。阿格拉斯曼:是的,如果可能的话,我想用番石榴,但不是eventbus,因为这是一个特定的功能,我想用一种更通用的方法来制作双调度的铅笔:我很好奇你的库,有没有什么例子?我是说“accept()方法还返回值“:public B accept(Visitor v)…我敢肯定这是聪明的,但这是代码生成规则吗?我想要一个不生成java代码的解决方案。想知道什么是避免编译时(JSR269)代码生成的rational吗?对我来说,任何基于运行时反射的解决方案都显然是低劣的(不是类型安全的)。也许我不知道编译时生成是什么意思,你能给我一个例子吗?示例:JPA2标准api使用JSR269注释处理器在编译时生成实体的静态元模型(代码生成由javac驱动)。这允许创建类型安全查询。由于通用解决方案返回值可以是任何类型,而不仅仅是字符串,因此字符串只是示例。您可以用另一个泛型替换字符串。像地图之类的东西
private EventFormatter eventFormatter = new EventFormatter();

public List<String> toStringList(List<Event> events) {
    return events.stream()
        .map(it -> eventFormatter.dispatch(it))
        .collect(Collectors.toList());
}
Map<Class<T extends Event>,Function<T,String>>