有没有更好的方法来跟踪订户变化?

时间:2017-08-30 13:39:33

标签: java design-patterns observable subscriber

假设我们有一个Client类,其中包含将消息发送到服务器队列的方法。它还订阅了队列,当服务器从任何已注册的客户端收到新消息时,它会向所有客户端发送通知:

public class Client {
   public void sendMessage(String message) {
      // Method to send messages to server
   }

   public void messageDelivered(String receivedMessage) {
      // This is a method subscribed successfull message delivering
   }
}

在另一个课程中,我想实现我的客户端,发送消息并检查它是否已成功发送:

public class ParentClass {
   protected boolean checkConnection() {
      Client client = new Client(); // Lets skip all configuration and connection details
      String testMessage = "Test message";
      client.sendMessage(testMessage);

      // Check that messageDelivered() was called in client with testMessage parameter

      return result;
   }
}

在父messageDelivered()方法中检查checkConnection()是否异步调用的最佳方法是什么?

我看到了在Client类中创建标志的简单解决方案,在传递消息时更新它,并在父类中由时间限制的某个循环中包装检查此标志。但是这个选项对我来说看起来很脏。也许在Java SDK中有一些更好的实践或“观察者”?

1 个答案:

答案 0 :(得分:2)

也许是这样的?

public class Client {
   private Runnable runnable;

   public void sendMessage(String message, Runnable runnable) {
      // Method to send messages to server
      this.runnable = runnable;
   }

   public void messageDelivered(String receivedMessage) {
      // This is a method subscribed successfull message delivering
      this.runnable.run();
   }
}

然后在Runnable中创建ParentClass并将其传递给客户。

public class ParentClass {

   protected boolean checkConnection() {
      Client client = new Client(); // Lets skip all configuration and connection details
      String testMessage = "Test message";
      // Check that messageDelivered() was called in client with testMessage parameter
      MyRunnable runnable = new MyRunnable();
      client.sendMessage(testMessage, runnable);

      try {
         runnable.wait( 10000 );  // Wait for 10 seconds
      } catch( InterruptedException e ) {
         e.printStackTrace();
      }

      return runnable.getResult();
   }
}

可运行的课程:

public class MyRunnable implements Runnable {

   private boolean result;

   public MyRunnable( ) {
      this.result = false;
   }

   @Override
   public void run( ) {
      this.result = true;
      this.notifyAll();
   }

   public boolean getResult( ) {
      return this.result;
   }

}