MetaController应该观察三个对象

时间:2013-09-01 02:26:54

标签: java multithreading model-view-controller observer-pattern observable

我陷入了精神循环,或者至少缺乏对如何实现观察者模式的理解。我打算Controller实现Observer ,因为它的意思是,从字面上看,它实际上是在控制它的实例。

观察到的对象延伸Observable 因为它们意味着由Controller逐字地观察。我该如何调用.addObserver(responseHandler);?另一个类为实例添加了一个观察者,实际上它实现了“Observer”接口?这不可能是正确的。

----- edit ----- responseHandler只是某个未知Controller的通用名称

顺便说一句,这个模式中是否存在使用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并不适合我。

这是Apache WeatherTelnet example的扩展,它是一种穷人Netty,允许并发脚本telnet和实时telnet响应,用于简单的MUD client,这需要实时处理未终止的telnet数据流,以及实时输出和用户输入。

3 个答案:

答案 0 :(得分:2)

您的Observable个对象应addObserver(yourController);。当他们改变时,他们应该拨打setChanged()然后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的引用,如果他也是修改它的人。

没有命名问题。需要在Observer中注册Observable,以便它知道如何通知他们。

警告:如果要在多线程环境中使用它,则必须小心使用控制器类中的共享数据。

答案 1 :(得分:1)

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

我认为从模式的角度来看,MetaController实际上不可能是Observer。也许它只是主人/创造者,从这里你的困惑。您是否需要MetaController才能收到来自Observable的通知?还是第三类对象?

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

答案 2 :(得分: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();
    }
}