设计模式之观察者模式

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
观察者模式是一种常用的设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,当主题对象状态发生变化时,它的所有观察者都会收到通知并更新自己的状态。 在C++中,观察者模式通常由一个抽象主题类和多个具体观察者类组成。抽象主题类中定义了添加、删除和通知观察者的接口,具体观察者类实现了更新自身状态的方法。 以下是一个简单的观察者模式示例: ```c++ #include <iostream> #include <vector> class Observer { public: virtual void update() = 0; }; class Subject { public: void attach(Observer* observer) { observers.push_back(observer); } void detach(Observer* observer) { for (auto it = observers.begin(); it != observers.end(); ++it) { if (*it == observer) { observers.erase(it); break; } } } void notify() { for (auto observer : observers) { observer->update(); } } private: std::vector<Observer*> observers; }; class ConcreteObserver1 : public Observer { public: void update() override { std::cout << "ConcreteObserver1 updated" << std::endl; } }; class ConcreteObserver2 : public Observer { public: void update() override { std::cout << "ConcreteObserver2 updated" << std::endl; } }; int main() { Subject subject; ConcreteObserver1 observer1; ConcreteObserver2 observer2; subject.attach(&observer1); subject.attach(&observer2); subject.notify(); subject.detach(&observer1); subject.notify(); return 0; } ``` 在上面的示例中,Subject类是抽象主题类,Observer类是抽象观察者类,ConcreteObserver1和ConcreteObserver2是具体观察者类。当Subject对象状态发生变化时,它会通知所有观察者更新自己的状态。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值