Java 将业务逻辑放在侦听器/执行器类中是一种糟糕的做法吗?

Java 将业务逻辑放在侦听器/执行器类中是一种糟糕的做法吗?,java,oop,Java,Oop,当使用诸如消息队列(RabbitMQ等)或调度框架(Quartz等)之类的框架时,需要实现框架的一些接口(Jobinterface或MessageListenerinterface)。通常的做法是避免将任何业务逻辑放入实现中,并立即委托给其他类。例如: class MyJob implements org.quartz.Job { private MyDelegate delegate = new MyDelegate(); @Override public void

当使用诸如消息队列(RabbitMQ等)或调度框架(Quartz等)之类的框架时,需要实现框架的一些接口(
Job
interface或
MessageListener
interface)。通常的做法是避免将任何业务逻辑放入实现中,并立即委托给其他类。例如:

class MyJob implements org.quartz.Job {
    private MyDelegate delegate = new MyDelegate();

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        String arg = context.getMergedJobDataMap().getString("arg");
        delegate.run(arg);
    }
}
从面向对象的角度来看,这是有意义的,因为单一责任原则。但除此之外,它只会导致类膨胀和过度分层的代码


委派有什么实际好处吗?

在许多情况下,您应该尽可能少地花费时间进行回调。例如,在Android中,花太多时间在UI回调(在UI线程中运行)会阻塞应用程序

来自Android:

具体来说,如果所有事情都发生在UI线程中,那么执行长时间操作(如网络访问或数据库查询)将阻塞整个UI。线程被阻止时,无法调度任何事件,包括图形事件。从用户的角度来看,应用程序似乎挂起了。更糟糕的是,如果UI线程被阻塞超过几秒钟(目前大约5秒钟),用户将看到臭名昭著的“应用程序未响应”(ANR)对话框


原则的好处在于有这么多的原则

在您的情况下,我会选择简单、直接的实现。
现在不需要提取业务逻辑;我们随时可以在需要时稍后再这样做。

委托的一个实际好处是,如果您需要切换到不同的框架/队列/接口/任何东西,或者如果您需要在当前框架/队列/接口/任何东西的基础上添加另一个,您可以重用您的业务逻辑(例如,您将您的业务方法公开为web服务,但希望添加一个REST API)。

我赞成将其分开(这是一个好主意,因为它允许依赖注入,如果使用的话)。我更感兴趣的是找到一种“自动方式”(泛型类型、反射代理等)为了避免手动创建这种“臃肿”的作业类型,但将保持这种状态。MyJob是否需要DI?我希望人们不要使用模拟委托和上下文来测试MyJob,以验证execute()中的两行代码这是针对一个不同的问题吗?这个问题似乎与将代码放在何处有关,而不是在哪个上下文中运行(委托或不委托)代码。@user2864740我正在使用Android作为在侦听器中运行代码的示例。将代码放在何处以及在哪个上下文中运行代码是链接的。运行操作的上下文与要运行的代码的位置没有直接关系-可以是来自sam中私有方法中与事件处理程序内联的委托对象/方法e类,在匿名类型中..@bayou Opinion-based:)它可以量化。在许多情况下,可以证明,针对未来事件进行低可能性设计是浪费的。同意。稍后,如果您发现该业务逻辑片段在系统的其他部分中被复制,则将其提取出来。