我陷入了精神循环,或者至少缺乏对如何实现观察者模式的理解。我打算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数据流,以及实时输出和用户输入。
答案 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();
}
}