【问题标题】:Java - signal/slots mechanismJava - 信号/槽机制
【发布时间】:2012-09-21 20:01:47
【问题描述】:

对于 Java 生态系统相对较新的人来说,是否有一种相当轻量级的方式来执行 Qt 和 Django 等框架对其信号/接收器系统所做的事情,其中​​组件可以说“我在做某事”,以及其他组件可以以相当松散耦合的方式处理它吗?

如果这个问题未能通过“单一客观答案”测试,我提前道歉。

编辑:为了添加更多上下文,这与 Web 服务的数据库驱动应用层有关。某些资源在持久化时还需要保存包含额外上下文信息的审计记录。在 Django 中,我会通过信号机制来做到这一点,或者使用几个现有的库之一来做到这一点。对于 Scala 程序,我使用回调函数制作了自己的 hacky 东西,但使用一流的函数更容易。我毫不怀疑诸如 Swing 之类的框架为这种事情提供了便利,但我(也许是不合理的)很想将这种依赖添加到目前相当普通的应用程序中(并不是说 Django 本身不是一个大量依赖原版 Python!)

【问题讨论】:

  • 你说的是event-driven models吗?
  • 在中型到大型组件级别,您有实现 2 个或更多方法的接口,我认为依赖注入已经赢得了如何耦合组件的战斗。在小层面(例如向 GUI 按钮提供操作),侦听器模式为王。
  • @normalocity:是的,但与 GUI 编程没有直接关系。
  • JavaFx 通过其绑定 API 提供了类似的机制。

标签: java signals-slots


【解决方案1】:

在 Java 中,至少在 UI 方面,这通常是通过 listener approach 完成的:您注册一个侦听器方法,该方法在特定事件发生时被调用。不过,它可能比 Qt 信号/插槽机制松散耦合要少一些……您可能会考虑的另一种方法是 java message service,它专为基于 Java EE 的客户端/服务器系统中的松散耦合通信而设计标准。

【讨论】:

  • 是的。但有时即使使用匿名类仍然是过多的结构。然而,QtJambi(用 Java 实现的 Qt 框架)利用反射来提供信号槽,恕我直言,导致更少的行数和更清晰的代码,但失去了类型安全性。
【解决方案2】:

如果您正在寻找提供类似于 Qt 的信号/槽机制的 Java 库,那么您应该查看sig4j。它是线程安全的、类型安全的,并且支持不同类型的连接。

注意:我是这个库的作者 :)

【讨论】:

    【解决方案3】:

    我同意其他关于事件驱动编程的 cmets/answers。

    您可能对http://eventbus.org 感兴趣。这允许您在全球范围内广播/接收事件,而无需在每个事件生产者上显式注册侦听器。

    【讨论】:

      【解决方案4】:

      在要接收信号的类中,可以定义一个Broadcastreceiver:

      private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
          @Override
          public void onReceive(Context context, Intent intent) {
              updateUI();
          }
      };
      
      @Override
      public void onPause() {
          super.onPause();
          getActivity().unregisterReceiver(broadcastReceiver);
      }
      
      @Override
      public void onResume() {
          super.onResume();
          getActivity().registerReceiver(broadcastReceiver, new IntentFilter(Constants.ACTION_UPDATE_PROFILE_UI)); // the constant is to identify the type of signal, it can be any string you want
      }
      

      然后在要发送信号的类中,只需执行以下操作:

      Intent signalIntent = new Intent(Constants.ACTION_UPDATE_PROFILE_UI);
      

      将您想要的数据类型添加到意图,然后像这样广播它:

      sendBroadcast(signalIntent);
      

      您可以在此处找到示例应用程序:

      https://github.com/nickfox/Update-Android-UI-from-a-Service

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多