设计模式:观察者模式(1)

简介

观察者模式属于行为模式,是一种非常常见的一种设计模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并且自动更新。通常使用与事件处理系统。

 结构:

主要为观察对象(主题)观察目标(观察者角色),为了符合DIP原则,不让他直接依赖于具体实现,我们需要将其抽象出来

1.抽象主题角色(Subject):把所有对观察者对象的应用保存到一个集合中,每个抽象主题角色都可以有任意数量的观察者。抽象主题提供一个接口,可以增加删除观察者角色。一般使用抽象类或者接口来实现。

2.抽象观察者角色(ConcreteSubject):为所有具体的观察者定义一个接口,在得到主题的通知时更新自己。

3.具体主题角色(Observer):在具体主题内部状态改变时,给所有登记过的观察者发出通知,具体主题角色通常用一个子类实现。通常用一个子类实现。

4.具体观察者角色(ConcrereObserver):实现抽象观察者角色所要求的更新接口,方便本身的状态与主题的状态协调。通常使用子类实现,吐过需要,具体观察者角色可以保存一个指向具体主题角色的应用。

 

观察者模式解决什么问题?

观察者模式主要解决的是轮询通知:当观察主题改变时会触发观察者发生改变。避免了不必要的资源浪费。

比如这样的场景:有一个气象站,你想要知道温度变了么,你需要打电话去询 温度变了么?气象站说变了,你才知道变了。

但是使用观察者模式,你只需要流一个电话,当温度有变化时候他会群发告诉你温度变了。

在实际上我们使用都是抽象类或者接口来进行沟通,这样才符合DIP原则。

代码案例   

(观察者模式分为推模式和拉模式,这里先从一个简单的案例开始理解,另外两个模式在观察者模式(2)中讲解)

这里依然使用开始举例的气象站

//抽象观察主题
public interface WeatherSubject {
  //注册
  void registerObserver(Observer ob);
  //删除
  void removeObserver(Observer ob);
  //通知
  void notifyObserver();
}

//抽象观察者角色
public interface Observer {
   //更新
  void update();
}
//具体观察者角色张三
public class ZhangSanOb implements Observer {
    //引入观察主题对象
	WeatherStation ws;

	public ZhangSanOb(WeatherStation ws) {

		this.ws = ws;
	}

	
	@Override
	public void update() {
		System.out.println("张三收到通知 更新温度:"+ws.getTemperature()+" 湿度:"+ws.getDamness());
	}

}
//具体观察者角色李四
public class LiSiOb implements Observer{
    WeatherStation ws;
    
    
    
	public LiSiOb(WeatherStation ws) {
		this.ws=ws;
		// TODO Auto-generated constructor stub
	}


    
	@Override
	public void update() {
		System.out.println("李四收到通知 更新温度:"+ws.getTemperature()+" 湿度:"+ws.getDamness());	
	}

}

 

//具体观察主题
public class WeatherStation implements WeatherSubject {
   //观察者集合
   List<Observer> list=new ArrayList<Observer>();
   //温度
   private int temperature=0;
   //湿度
   private int damness=0;
      
	@Override
	public void registerObserver(Observer ob) {
		list.add(ob);

	}
	@Override
	public void removeObserver(Observer ob) {
		list.remove(ob);
		
	}
	@Override
	public void notifyObserver() {
		//遍历观察者集合 给每个观察者进行更新
		for (Observer observer : list) {
			observer.update();
		}
		
	}	
	
    //set方法调用时 说明主题发生改变,所以我们需要调用通知方法
	public void setTemperature(int temperature) {
		this.temperature = temperature;
		notifyObserver();
	}

	public void setDamness(int damness) {	
		this.damness = damness;
		notifyObserver();
	}

	//省略get方法
}

测试结果

public class Client {
  public static void main(String[] args) {
  	  //创建观察主题对象
	  WeatherStation ws=new WeatherStation();	 	  
	  //创建观察者对象 张三 李四
	  ZhangSanOb zsOb=new ZhangSanOb(ws);
	  LiSiOb liSiOb=new LiSiOb(ws);
	  //为观察目标注册观察者
	  ws.registerObserver(zsOb);
	  ws.registerObserver(liSiOb);
	  //设置温度
	  ws.setDamness(51);
	  //设置湿度
	  ws.setTemperature(-5);
	  
   }
}

结果:
张三收到通知 更新温度:0 湿度:51
李四收到通知 更新温度:0 湿度:51
张三收到通知 更新温度:-5 湿度:51
李四收到通知 更新温度:-5 湿度:51

看过设计模式中的设计原则的同学应该能看的出来 这里我们每个观察者对象都引用了一个观察目标的一个对象,这样是不合理的设计  所以我把真正的推模式案例和拉模式 写在设计模式专栏中:观察者模式(2)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
观察者模式是一种常用的设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,当主题对象状态发生变化时,它的所有观察者都会收到通知并更新自己的状态。 在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对象状态发生变化时,它会通知所有观察者更新自己的状态。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值