观察者模式

基本定义:观察者模式是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实作事件处理系统。 

 实例:公司前台,观察老板动向

源代码:

package observer;

import java.util.ArrayList;

public class observer {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Secretary dabao =new Secretary();//前台秘书大宝
		//看股票同事
		StockObserver per1 =new StockObserver("小明",dabao);
		StockObserver per2 =new StockObserver("小红",dabao);
		//前胎记下两位同事
		dabao.Attach(per1);
		dabao.Attach(per2);
		//发现老板回来
		dabao.setAction("老板回来了");
		//通知两个同事
	    dabao.Notify();	
	}

}
class Secretary//前台秘书类——Sercretary依赖StockObserver
{//同时列表组合,用来添加请求帮忙的同事
	private ArrayList<StockObserver> observers = new ArrayList<StockObserver>();
	private String action;
	public void Attach(StockObserver observer ) {
		observers.add(observer);
	}
	public void Notify()//通过
	{
		for(int i=0;i<observers.size();i++)
		{
			observers.get(i).Update();
		}
	}
	public String getAction() {
		return action;
	}
	public void setAction(String action) {
		this.action=action;
	}
}
class StockObserver{//看股票同事类
	private String name;
	private Secretary sub;
	public StockObserver(String name,Secretary sub) {
		 this.name=name;
		 this.sub=sub;
	}
	public void Update()//得到前台的通知,赶快采取行动
	{//观察者类需要前台的状态
		System.out.println(sub.getAction()+name+"关闭股票性情,继续工作!");
	}
	
}

å¨è¿éæå¥å¾çæè¿°

 改进:耦合度太高,抽象类实现解耦合

package observer;

import java.util.ArrayList;
import java.util.Observable;

public class observer2 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Subject dabao =new Boss();
		//看股票同事
		StockObserver per1 =new StockObserver("小明",dabao);
		NBAObserver per2 =new NBAObserver("小红",dabao);
		//前胎记下两位同事
		dabao.Attach(per1);
		dabao.Attach(per2);
		//发现老板回来
		dabao.setAction("老板回来了");
		//通知两个同事
	    dabao.Notify();	
	}

}
 abstract class Subject//抽象通知者
{//同时列表组合,用来添加请求帮忙的同事
	abstract void Attach(Observer observer);//添加观察者
	abstract void Detach(Observer observer);//删除观察者
	abstract void Notify();//通知观察者
	private String action;

	
	public String getAction() {//老板状态
		return action;
	}
	public void setAction(String action) {
		this.action=action;
	}
}
class Boss extends Subject{

	private ArrayList<Observer> observers = new ArrayList<Observer>();
	@Override
	void Attach(Observer observer) {
		// TODO Auto-generated method stub
		observers.add(observer);
	}

	@Override
	void Detach(Observer observer) {
		// TODO Auto-generated method stub
		observers.remove(observer);
	}

	@Override
	void Notify() {
		// TODO Auto-generated method stub
		for(int i=0;i<observers.size();i++) {
			observers.get(i).Update();
		}
	}
	
}
abstract class Observer{//看股票同事类
	protected String name;
	protected Subject sub;
	public Observer(String name,Subject sub) {
		 this.name=name;
		 this.sub=sub;
	}
	public abstract void Update();
	
}
class StockObserver extends Observer{

	public StockObserver(String name, Subject sub) {
		super(name, sub);
		// TODO Auto-generated constructor stub
	}

	@Override
	public void Update() {
		// TODO Auto-generated method stub
	     //观察者类需要前台的状态
			System.out.println(sub.getAction()+name+"关闭股票性情,继续工作!");
		
	}


	
}
class NBAObserver extends Observer{

	public NBAObserver(String name, Subject sub) {
		super(name, sub);
		// TODO Auto-generated constructor stub
	}

	@Override
	public void Update() {
		// TODO Auto-generated method stub
		System.out.println(sub.getAction()+name+"关闭NBA,继续工作!");
	}
	
}

观察者模式模板:

å¨è¿éæå¥å¾çæè¿°

package observer;

import java.util.ArrayList;

public class observer3 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ConcreteSubject dabao =new ConcreteSubject();
		dabao.Attach(new ConcreObserver("X",dabao));
		dabao.Attach(new ConcreObserver("Y",dabao));
		dabao.Attach(new ConcreObserver("Z",dabao));
	    dabao.setAction("ABC");
	    dabao.Notify();
	}

}
 abstract class Subject//抽象通知者
{//同时列表组合,用来添加请求帮忙的同事
	private ArrayList<Observer> observers = new ArrayList<Observer>();
	public void Attach(Observer observer)//添加观察者
	{
		observers.add(observer);
	}
	
	public void Detach(Observer observer){
		observers.remove(observer);
	}//删除观察者

	public void Notify()//通知观察者
	{
		for(int i=0;i<observers.size();i++) {
			observers.get(i).Update();
		}
	}
	
}
class ConcreteSubject extends Subject{
	private String action;

	public String getAction() {
		return action;
	}

	public void setAction(String action) {
		this.action = action;
	}
	
}
abstract class Observer{//看股票同事类
 abstract void Update();
	
}
class ConcreObserver extends Observer{

	private String name;
	private String action;
	private ConcreteSubject sub;
	
	public ConcreObserver(String name, ConcreteSubject sub) {
		super();
		this.name = name;
		this.sub = sub;
	}

	@Override
	void Update() {
		// TODO Auto-generated method stub
		this.action=sub.getAction();
		System.out.println("观察者"+name+"的新的状态是"+action);
	}

	
}

JAVA中的观察者案例
狼来了——源代码:

package observer;

import java.util.Observer;
import java.util.Observable;

public class observer4 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
        Wolf wolf =new Wolf("狼");
        Sheep sheep1 =new Sheep("羊1");
        Sheep sheep2 =new Sheep("羊2");
        Sheep sheep3 =new Sheep("羊3");
        //注册观察者,sheep1和2加入3不加入;
        wolf.addObserver(sheep1);
        wolf.addObserver(sheep2);
        String state="饿";
        wolf.shout(state);
	}

}
class Wolf extends Observable{//被观察者类
	private String name;
	Wolf(String name){
		this.name=name;
	}
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void shout(String state) {
		System.out.println(this.getName()+"shouting");
		this.setChanged(); this.notifyObservers(state);
	}
}
class Sheep implements Observer{

	private String state ="eating";
	private String name;
	
	public Sheep(String name) {
		super();
		this.name = name;
	}

	public String getState() {
		return state;
	}

	public void setState(String state) {
		this.state = state;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}


	@Override
	public void update(Observable arg0, Object arg1) {
		// TODO Auto-generated method stub
		Wolf w=(Wolf)arg0;
		System.out.println(w.getName()+"shouting and"+arg1+" "+this.getName()+"running------");
		setState("running");
	}
	
}

观察者模式的应用
1. 何时使用

  • 一个对象状态改变,所有的依赖对象都将得到通知

2. 方法

  • 使用面向对象技术

3. 优点

  • 观察者和被观察者是抽象耦合的
  • 建立了一套触发机制

4. 缺点

  • 如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间
  • 如果观察者和观察目标间有循环依赖,可能导致系统崩溃
  • 没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的

5. 使用场景

  • 关联行为场景
  • 事件多级触发场景
  • 跨系统的消息变换场景,如消息队列的处理机制


6. 应用实例

  • 手机丢了,委托别人给其他人发消息通知
  • 通知老师/老板来了
  • 拍卖,拍卖师观察最高标价,然后通知给其它竞价者竞价
  • 在一个目录下建立一个文件,会同时通知目录管理器增加目录,并通知磁盘减少空间,文件是被观察者,目录管理器和磁盘管理器是观察者
  • 猫叫了一声,吓着了老鼠,也惊到了主人,猫是被观察者,老鼠和人是观察者


7. 注意事项

  • 避免循环引用
  • 如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式
     
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值