观察者模式主要应用在:
1、对一个对象状态的更新,需要其他对象同步更新,而且其他对象的数量动态可变。
2、对象仅需要将自己的更新通知给其他对象而不需要知道其他对象的细节。
观察者主要的优势有:
1、 观察者和被通知者之间实现松耦合关系
2、 观察者在发送通知时无需知道具体通知到哪个被通知者
在Java语言的java.util库里面提供了一个Observable类以及一个Observer接口,构成JAVA语言对观察者模式的支持。
本节通过一个示例展示观察者模式:
我们知道java中对配置文件.properties的处理是通过Properties类来完成的,但是当Java将配置文件读取后,文件数据是被缓存到内存中的。在有些程序中特别是一些网站中,希望当配置文件改变时不重启系统就完成配置的更新。
配置文件:test.properties
name=tidu2chengfo
age=110
观察者:ParameterListener.java
import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.Observable;
public class ParameterListener extends Observable{
private String _filePath;
public ParameterListener(String filePath){
this._filePath = filePath;
}
public void observ() throws IOException, InterruptedException{
File file = new File(_filePath);
WatchService watchService = FileSystems.getDefault().newWatchService();
Paths.get("d:/test").register(watchService,StandardWatchEventKinds.ENTRY_MODIFY);
while(true){
WatchKey key= watchService.take();
for(WatchEvent<?> event:key.pollEvents())
{
Stringfilename = file.getName().toString();
Stringname = event.context().toString();
if(name.equals(filename) && event.kind() ==StandardWatchEventKinds.ENTRY_MODIFY)
{
this.setChanged();
this.notifyObservers();
}
}
if(!key.reset())
{
break;
}
}
}
public static void main(String args[]) throws Exception{
String filePath = "d:/test.properties";
ParameterListener listener = new ParameterListener(filePath);
listener.addObserver(new Parameter(filePath));
listener.observ();
}
}
被通知者:Parameter.java
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Observable;
import java.util.Observer;
import java.util.Properties;
public class Parameter implements Observer {
private static Properties_prop;
private static String filePath;
public Parameter(String filePath){
this.filePath = filePath;
}
@Override
public void update(Observable o, Object arg) {
if(_prop == null){
_prop = new Properties();
}
try {
FileInputStream in = new FileInputStream(filePath);
_prop.load(in);
in.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(getValue("name") + "-" + getValue("age"));
}
public static String getValue(String key){
if(null != _prop && _prop.containsKey(key)){
return _prop.getProperty(key);
}
return null;
}
}