0

我陷入了一个心理循环,或者至少对如何实现观察者模式缺乏了解。我打算Controller实现的目的是Observer 因为它实际上是为了观察它所控制的实例。

被观察到的对象之所以扩展,是Observable 因为它们意味着被观察,字面意思是,被Controller. 我调用.addObserver(responseHandler);什么?另一个类向实例添加了一个观察者,从字面上看,它实现了“观察者”接口?这不可能。

------edit----- responseHandler 只是一些未知控制器的通用名称

顺便说一句,这种模式在 Java 中实现是否存在命名问题,或者只是我缺乏理解?

这是控制器,它现在已经变成了控制器的控制器:

public class MetaController implements Observer {

    private final static Logger LOG = Logger.getLogger(MetaController.class.getName());
    private Printer telnetPrinter = new Printer();
    private telnetDataProcessor telnetDataProcessor = new telnetDataProcessor();
    private StringReader stringReader = new StringReader();
    private final ConcurrentLinkedQueue<Character> telnetData = new ConcurrentLinkedQueue();

    public MetaController() {
    }

    //the printer and processor each spawn their own thread so that they don't
    //block each other waiting for each other
    public void readPrintParse(final InputStream inputStream) throws SocketException, IOException {
        telnetPrinter.print(inputStream, telnetData); //populate telnetData in its own thread
        telnetDataProcessor.read(telnetData); //process telnetData in its own thread
    }

    //the StringReader just looks for particular keywords like "press enter to continue"
    //so that some phrases will trigger a response
    //commands may also be typed manually by the user (not implemented yet)
    @Override
    public void update(Observable o, Object arg) {
        //when telnetDataProcessor sends a String, send that String on to stringReader
        String cmd = stringReader.parse(null); //parse what and how?
        //send the command string back to the telnetClient
    }
}

不幸的是,直接阅读API对我没有启发。

这是 ApacheWeatherTelnet 示例的扩展,是一种穷人 Netty,允许对简单的MUD 客户端进行并发脚本远程登录和实时远程登录响应,这需要实时处理未终止的远程登录数据流,以及实时输出和用户输入。

4

3 回答 3

2

你的Observable对象应该addObserver(yourController);. 当他们改变时,他们应该调用setChanged()then notifyObservers()。如果您需要自定义行为,您显然可以覆盖这些方法。

例如:

MetaController controller = new MetaController();
Observable observable1 = new Weather1();
Observable observable2 = new Weather2();
Observable observable3 = new Weather3();
observable1.addObserver(controller);
observable2.addObserver(controller);
observable3.addObserver(controller);

如果他也是修改控制器的人,您还可以提供Observable对控制器 ( ) 的引用。Observer

没有命名问题。Observers 需要向 s 注册,以便Observable它知道如何通知它们。

注意:如果这意味着要在多线程环境中使用,则必须小心在控制器类中使用共享数据。

于 2013-09-01T02:30:28.967 回答
1

创建实现对象的对象/类Observable应调用addObserver传递MetaController对象的方法(以其角色Observer)。

我认为从模式的角度来看,你MetaController不可能真正成为一个。Observer也许它只是所有者/创造者,从这里你的困惑。您需要MetaController接收来自Observables 的通知吗?还是第三类对象?

我这样说是因为作为您写的问题的一部分,.addObserver(responseHandler);而不是.addObserver(metaController);.

于 2013-09-01T02:40:49.473 回答
0

这是我想出的:

package telnet;

import java.io.IOException;
import java.io.InputStream;
import java.net.SocketException;
import java.util.Observable;
import java.util.Observer;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.logging.Logger;

public class Controller implements Observer {

    private final static Logger LOG = Logger.getLogger(Controller.class.getName());
    private Printer telnetPrinter = new Printer();
    private telnetDataProcessor telnetDataProcessor = new telnetDataProcessor();
    private StringReader stringReader = new StringReader();
    private final ConcurrentLinkedQueue<Character> telnetData = new ConcurrentLinkedQueue();

    public Controller() {
    }

    public void readPrintParse(final InputStream inputStream) throws SocketException, IOException {
        telnetPrinter.print(inputStream, telnetData);
        telnetPrinter.addObserver(this);
        telnetDataProcessor.read(telnetData);
        telnetDataProcessor.addObserver(this);
        stringReader.addObserver(this);
    }

    @Override
    public void update(Observable o, Object arg) {
        System.out.println("updated...");
        String s = telnetDataProcessor.getString();
    }
}
于 2013-09-01T03:25:31.237 回答