1.这几天做设计模式作业的时候,遇到了观察者模式,顺便学习了下观察者模式,感觉学习完后,瞬间让我想起了android里面的一些方法。估计哪些方法就是用到了观察者模式。当Model层的数据改变了通知相应的view更换数据。
观察者:(Observer)将自己注册到被观察对象(Subject)中,被观察对象将观察者存放在一个容器(Container)里。
被观察者:被观察对象发生了某种变化(如图中的SomeChange),从容器中得到所有注册过的观察者,将变化通知观察者。
Uml图:
被观察者的数据改变了通知view更换数据:就应该有俩个比较重要的方法。addobServer()添加观察者,将这个oberver对象保存到集合中。notifyObServer() 通知oberver对象,更新数据。
在这里我将以一个例子来加以说明。这个例子让我觉得观察者模式很简单,运行结果如下。。
每当点击serach后,我圈起来的部分就会改变,相信这样的场景大家遇到很多。
现在我开始贴代码了:结合代码来理解观察者模式:
首先确定谁是观察者,谁是被观察者。被观察者的改变会引起观察者的改变,因此很显然。“选择车辆” 是一个被观察者,“车的图片”和“车子的说明” 是观察者。
observer接口的声明:
public interface Observer {
public void update(Observable subject);
}
很明显就是一个 update(obserable subject)方法,obserable 表示的是被观察者接口。接口定义如下:
obserable接口声明:
public interface Observable {
public void notifyObservers();//通知所有的观察者更新数据
public void register(Observer obs);//注册一个观察者
}
正如前面所说:obserable接口中,至少有一个addobserver(observer obs)方法,和一个notifyObserver().方法、。
通常情况下:Model层充当被观察者的角色,view层充当观察者角色。
下面是Model层的代码:
import java.io.*;
import java.net.URL;
import java.net.URI;
import javax.swing.*;
import java.util.*;
/*
* 这个类是被观察的类,当这个类中数据改变的时候,可以通
* 知所有的观察者改变数据
*/
public class CarModel implements Observable{
<span style="background-color: rgb(255, 255, 102);"> private Vector<Observer> observersList;</span>
private ImageIcon imgIcon;
private URL url;
private String[] carNameList;
private String carSelected;
private String bitPrice;
private boolean isBitBtnClicked = false;
private boolean isSearchBtnClicked = false;
static final String CARFILES = "CarFiles/";
static final String CARIMAGES = "CarImages/";
public CarModel(){
observersList = new Vector<Observer>();
carNameList=new String[200];
}
public void setCarList(String[] cars){
carNameList = cars;
}
public String[] getCarList(){
return carNameList;
}
public void setSelectedCar(String sCar){
carSelected = sCar;
}
public String getSelectedCar(){
return carSelected;
}
public void setBitPrice(String bPrice){
bitPrice =SingTon.getInstence().saveprice(carSelected, bPrice);
}
public String getBitPrice(){
return bitPrice;
}
public void setFileUrl(){
try{
String fileURLStr = CARFILES + carSelected+ ".html";
URI uri = (new File(fileURLStr)).toURI();
url = uri.toURL();
}
catch (IOException e){
e.printStackTrace();
}
}
public URL getCarFileURL(){
return url;
}
public void setupImageIcon(){
String iconStr = CARIMAGES + carSelected+".jpg";
imgIcon = createImageIcon(iconStr);
}
public ImageIcon getImageIcon(){
return imgIcon;
}
public void setBitBtnClickInfo(boolean opt){
isBitBtnClicked = opt;
}
public boolean isBitBtnClicked(){
return isBitBtnClicked;
}
public void setSearchBtnClickInfo(boolean opt){
isSearchBtnClicked = opt;
}
public boolean isSearchBtnClicked(){
return isSearchBtnClicked;
}
/*
* 重写的这些方法。
* @see Observable#register(Observer)
*/
<span style="background-color: rgb(255, 255, 102);"> public void register(Observer obs){
observersList.addElement(obs);
}
public void notifyObservers() {
for (int i = 0; i < observersList.size(); i++) {
Observer observer = (Observer) observersList.get(i);
observer.update(this);
}
}</span>
/*****************************************/
protected ImageIcon createImageIcon(String path){
java.net.URL imgURL = getClass().getResource(path);
if (imgURL != null) {
return new ImageIcon(imgURL);
}
else {
System.err.println("Couldn't find file: " + path);
return null;
}
}
}
核心业务:我们不需要懂。只需要看我标记颜色的部分。被观察者改变通知观察者变化,那么被观察者中必须有
观察者的引用。如上图所示:作为被观察者的Model,里面有一个集合专门保存观察者,这样在notifyobserver()方法中,通过循环不断调用观察者的update方法,这样就可以及时更新view了。
Observer接口的实现代码如下:
import java.io.*;
import java.net.URL;
class CarFileInfoView implements Observer{
private String fileName;
private URL url;
private CarModel model;
private CarAuctionGUI cg;
public CarFileInfoView(CarModel cmodel,CarAuctionGUI cg){
model = cmodel;
this.cg=cg;
}
public void update(Observable subject){
if ((subject == model) && (model.isSearchBtnClicked())){
URL url = model.getCarFileURL();
cg.setCarFileToEditorPane(url);
}
}
}
CarFileInfoView 这个类就是专门负责控制车辆图片的。
总结下观察者模式:
观察者和被观察者都应该有各自 的接口,也就是observer接口和obserable接口。observer接口中最起码有一个uodate(observer sub)方法;obserable接口中 至少有addobserver(observer ob) 和 notifychanged()方法。
使用情况:
1) 当一个抽象模型有两个方面, 其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
2) 当对一个对象的改变需要同时改变其它对象, 而不知道具体有多少对象有待改变。
3) 当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之, 你不希望这些对象是紧密耦合的。
java项目代码:http://download.csdn.net/detail/qq_25984015/9550529