`
砺雪凝霜
  • 浏览: 151715 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

设计模式——观察者设计模式

阅读更多

1 概念

      观察者设计模式是对象的行为模式,又叫做发布-订阅模式模型-视图模式源-监听器模式从属者模式
      观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态
上发生变化时,会通知所有观察者对象,使他们能够自动更新自己。

2 观察者模式的结构

     抽象主题(Subject)角色:主题角色把所有观察者对象的引用保存在一个聚集(比如Vector对象)里,每个主题都可以有任何数量的观察者。抽象主题提供:所有观察者的集合(observers)增加(attach)和删除(detach)观察者方法通知观察者(notifyObservers)的方法,主题角色又叫做抽象被观察者,一般用一个抽象类或者一个接口实现。
  

 

  抽象观察者(Observer)角色:为所有的具体观察者定义一个接口,在得到主题的通知时更新自己,这个接口叫做更新接口,抽象观察者一般用一个抽象类或者一个接口来实现,如图所示,更新接口中只有一个update方法,这个方法叫做更新方法。
   

 

    具体主题方(ConcreteSubject)角色:将所有关联状态存入具体观察者对象,在具体主题的内部状态(state)改变时给所有登记过的观察者发出通知。具体主题角色又叫做具体被观察者角色,具体主题角色通常用一个具体子类实现,它既有抽象主题的成员变量vector(所有观察该主题的集合),还实现了attach(增加观察者)、detach(删除观察者)、notifyObservers(通知观察者)方法,并且自己还定义了一个change(改变状态)方法,state(状态)变量。

 

    具体观察者(ConcreteObserver)角色:它实现了抽象观察者所要求的接口,以便在主题状态发生改变时通知观察者。主题与观察者是一个合成关系,在主题角色中的Vector中可以有多个观察者接口(Observer),在具体主题中是不知道Observer的具体类型的,这就使得具体主题对象可以动态的维护一系列的对象观察者对象引用,并且在特定的时候调用每一个观察者共有的update方法。


3 观察者设计模式的demo

3.1 定义一个抽象主题接口subject

 

/**
 * 抽象主题(Subject)角色
 * @author Mrliu
 *
 */
public interface Subject {
    public Vector<Observer> observerVector = new Vector<Observer>();
    public void attach(Observer observer);
    public void detach(Observer observer);
    public void notifyObservers();
}

 

3.2 定义一个实现ConcreateSubject类,它实现了Subject接口

 

package com.liuyu.subject;

import com.liuyu.observer.Observer;

public class ConcreateSubject implements Subject {
	private boolean state;

	// 添加观察者(订阅)
	@Override
	public void attach(Observer observer) {
		observerVector.add(observer);
	}

	// 删除观察者(取消订阅)
	@Override
	public void detach(Observer observer) {
		if (observer != null && observerVector.contains(observer)) {
			observerVector.remove(observer);
		}
	}

	// 通知所有观察者,调用更新方法
	@Override
	public void notifyObservers() {
		for (Observer observer : observerVector) {
			observer.update();
		}
	}

	// 主题状态发生改变,通知所有观察者,调用更新方法
	public void changeState(boolean state) {
		if (state) {
			this.notifyObservers();
		}
	}

	public boolean isState() {
		return state;
	}

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

}

  

3.3 定义了一个抽象观察者对象,Observer接口

 

package com.liuyu.observer;
/**
 * 抽象观察者(Observer)角色
 * @author Mrliu
 *
 */
public interface Observer {
   public void update();
}

  

3.4 定义个ConcreateObserver(具体观察者对象),它实现了Observer接口

 

package com.liuyu.observer;

/**
 * 具体观察者(ConcreteObserver)角色
 * 
 * @author Mrliu
 * 
 */
public class ConcreateObserver implements Observer {
	private String observerName;

	public ConcreateObserver() {}

	public ConcreateObserver(String observerName) {
		super();
		this.observerName = observerName;
	}

	@Override
	public void update() {
		System.out.println("==== "+ observerName +"update ====");
	}

	public String getObserverName() {
		return observerName;
	}

	public void setObserverName(String observerName) {
		this.observerName = observerName;
	}

}

 

 

3.5 编写一个主函数,生成一个主题和2个观察者(订阅者)对象,然后调用主题的changeState方法

 
package com.liuyu.main;

import com.liuyu.observer.ConcreateObserver;
import com.liuyu.subject.ConcreateSubject;

public class TestDemo {
    public static void main(String[] args){
    	ConcreateSubject subject = new ConcreateSubject();
    	subject.attach(new ConcreateObserver("观察者一"));
    	subject.attach(new ConcreateObserver("观察者二"));
    	subject.changeState(true);
    }
}
 
运行结果

    生活中运用的场景:大家都知道消息推送,我们在App客户端设置了允许推送后,当有新闻更新后,消息服务器(Suject)就会把新闻推送给客户端(observer),而没有设置允许推送的客户端是收不到推送过来的消息的。

 

4 观察者的效果

4.1观察者的优点

    (1) 观察则模式在被观察者和观察者之间建立一个抽象的耦合。被观察者角色所知道的只是一个具体观察者聚合,每一个具体观察者都符合一个抽象观察则的接口,被观察者并不认识任何一个具体观察者,它只知道他们又一个共同的接口。这样被观察者和观察者就不会紧密地耦合到一起。

 

  (2) 观察者模式支持广播通讯。被观察者会向所有的登记过的观察者发出通知

 

4.2观察者模式有以下缺点

   (1) 如果一个被观察者有很多观察者的话,将所有的观察者通知到会花费很多时间 

 

   (2) 如果被观察者之间有循环依赖的话,被观察者会触发他们之间进行循环的调用,导致崩溃,在使用观察者模式时,特别要注意这一点。

 

   (3) 如果对观察者的通知时通过另外的线程进行异步投递的话,系统必须保证投递是以合适的方式进行的。

 

   (4) 虽然观察者模式可以随时使观察者知道所观察的对象发生了变化,但是观察者模式没有相应的机制使观察者知道所有的对象是怎么发生改变的。

 

 

 

 

 

 

 

 

 

  • 大小: 8.2 KB
  • 大小: 4.6 KB
  • 大小: 4.3 KB
  • 大小: 4.3 KB
  • 大小: 6.7 KB
1
0
分享到:
评论
2 楼 砺雪凝霜 2015-05-02  
哈哈,主要发现自己写的代码太垃圾了,想研究一下架构
1 楼 javaboy8282 2015-05-02  
最近我也在看23种设计模式,相互学习了   

相关推荐

Global site tag (gtag.js) - Google Analytics