当前位置: 首页 > 知识库问答 >
问题:

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

王叶五
2023-03-14

访问者模式在某些情况下会产生不必要的复杂性和样板文件(许多accept方法),而且完全一般化对我来说似乎是不可能的(accept()方法返回值也是)。所以我认为我的另一个解决方案。

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

例如,番石榴在其Eventbus中具有类似的功能,这使得将特定类型的事件与@Subcribe注释方法相匹配成为可能,因此我正在寻找一个类似的库,以一般方式使这成为可能。

魔术界面:

/**  @param <R> - return type  * @param <I> - element super type */
public interface MagicDoubleDispatch<R, I>{
    R dispatch(I element);
}

我的“访客”实现(应自动调用正确的方法)

public class EventFormatter extends MagicDoubleDispatchImpl<String, Event> {
    private String format(AddedEmployeeEvent event) {
        return String.format("Added new employee: %s with id %s", event.name, event.employeeId);
    }
    private String format(DeletedEmployeeEvent event) {
        return String.format("Deleted employee:(%s) %s (this can't be undone!)", event.employeeId, event.name);
    }
    private String format(AddedTimeCardEvent event) {
        return String.format("Timecard of %s has been added to %s", event.date, event.employeeName);
    }
}

我希望这是一个库(例如):

public abstract class MagicDoubleDispatchImpl<R, I> implements MagicDoubleDispatch<R, I> {
    //I want this ... probably using reflection as EventBus, I don't care..
}

客户代码:

private EventFormatter eventFormatter = new EventFormatter();

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

共有2个答案

越安翔
2023-03-14

您可以创建一个 Map,将事件扩展为键的类和一个将事件转换为字符串的函数。

Map<Class<T extends Event>,Function<T,String>>

如果您想要一些奇特的东西,您可以使用注释并基于这些注释创建注册表(使用spring很容易),但基本上最终结果是相同的。

事件格式根据给定事件的类型在映射中查找它的格式化程序,并应用相应的函数。如果您在事件类和格式化程序之间有1到1的映射,那应该没问题。

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

顾光明
2023-03-14

不确定你所说的“接受()方法也返回值”是什么意思,但无论如何,在代码生成器的帮助下,访问者模式可以非常轻量级:看看https://github.com/derive4j/derive4j-它提供了一种模式匹配语法,可以使您的代码非常易读。

也没有其他技术/库能像访问者模式一样提供如此多的类型安全。

 类似资料:
  • 问题内容: 刚刚发现了Guava库项目。 这些与GWT兼容吗? 问题答案: 从该页面的介绍性PDF中, 您可以在…上使用这些库。 在JDK 6上 在Android上, 我们认为。需要志愿者来帮助我们进行测试。 在Google App Engine上, 我们认为。需要志愿者来帮助我们进行测试。 在GWT上-参差不齐! 由于GWT的JDK库支持 可能参差不齐,也许是2/3,所以到目前为止,这些库中的东

  • 问题内容: 我在commons- lang中使用了简单的DTO。现在,我尝试使用Google Guava代替Apache Commons库。我在番石榴找到了。但是如果班上有很多成员,这太冗长了。例如: 如果我使用commons-lang,则简单得多: 有什么更好的方法可以用Guava而不是commons-lang 来实现? 番石榴文件 问题答案: 我有番石榴的小招。我将 IntelliJ IDEA

  • 问题内容: 在过去的几周内,我一直在尝试使用番石榴的MapMaker查找理想的缓存实现。 根据我所学的知识,我的下一个尝试将弃用软值,以使用maximumSize和expireAfterAccess: 哪里 但是,我仍然要解决的一个问题是,一旦它们用完了,即使对象很容易到达,此实现也将逐出对象。这可能会导致环境中漂浮着具有相同UID的多个对象,而这是我所不希望的(我相信我试图实现的目标称为规范化)

  • 问题内容: 我的应用程序对它的依赖程度很高或更高 但是我也在使用它与> 22.0的番石榴版本不兼容,如下所述: https://github.com/SeleniumHQ/selenium/issues/4381 我对Java很陌生,这里最好的做法是什么? 我已经研究过类加载器,但是看起来像是一个很深的兔子洞。 问题答案: 由于您对 使用的依赖度很高,因此 可能会遇到麻烦。但是 Selenium发

  • 问题内容: 我想知道哪个更有效,为什么? 1) 要么 2) 问题答案: 我看不出您为什么要在此处使用builder的任何原因: 比在这种情况下制作一个更具可读性, 不会推断通用类型,并且在用作单行代码时必须自己指定类型, (来自docs) 在与另一个不可变集合调用时 做得很好( 尝试避免在安全的情况下实际复制数据 ), (从源) 调用以前创建的,同时避免为零元素和一元素集合创建任何列表(分别返回空

  • 我想为番石榴设个坑(http://pitest.org/)进行突变熟练度测试,但我在尝试运行时出现以下错误。这是我得到的错误: 基本上,要么PIT没有检测到测试,要么测试在PIT中运行不正常,所有测试都失败了。我读了这篇文章:JUnit测试通过,但PIT说套件不是绿色的,我认为“您的代码库是否包含可变静态状态?(例如在单例中)”是问题所在,但我不知道如何修复它。如果测试套件有一些隐藏的顺序依赖关系

  • 我的 Spark 版本是 2.2.0,它在本地工作,但在具有相同版本的 EMR 上,它给出了以下异常。

  • 我对番石榴很陌生(说实话,我不是“很新”,我是这个主题的新手),所以我决定浏览一些文档,在阅读本文时感到非常惊讶: 我不明白这个方法的意义。这意味着,与其这样做,不如: (如果myObject为null,这可能会导致) 我应该用 如果为空,这将抛出一个,如果它不是空,则返回。 我很困惑,这可能是有史以来最愚蠢的问题,但是... 这有什么意义?这两条线和我能想到的任何情况下的结果是完全一样的。 我甚