一:定义观察者模式
定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都收到通知并自动更新。
二:观察者模式类图:
三:观察者模式的自我理解:
(1)<<interface>>Observer: 定义了观察者更新的操作接口
(2)<<interface>>Subject:定义了对象的注册,注销和通知数据更新的三个接口
(3)ConcreteObserver类,主要是实现了<<interface>>Observer的更新操作
(4)ConcreteSubject类,我们也可以称管理类,主要是实现了<<interface>>Subject定义的注册,注销和通知数据更新的三个接口,其中的一个关键变量-List<ConcreteObserver> concreteObserver,这个变量主要是对所有的观察者进行管理,当数据改变时,遍历所有的观察者,进行相对应的操作。
四:我的一个小例子:
这个例子是Head First设计模式(中文版)这本书中最后的一个小程序,我在android上实现了。这个例子是当我点击一个按键时,有二个观察者,一个观察者(天使)会说:亲,我是天使,我对于您的点击,我的答复是:我爱你!!,另一个观察者(恶魔)会说:亲,我是恶魔,我对于您的点击,我的答复是:我恨你!!
在这个例子中,我应用了单例模式,观察者模式。
(1)<<interface>>Observer:
public interface IClickListernObserver {
public void onClickToUpdate();
}
(2)ConcreteObserver类-----AngelObserver:
public class AngelObserver implements IClickListernObserver {
private static AngelObserver instance;
private IAngelClickLister myIAngelClickLister;
public AngelObserver(){
ClickListerManager.getInstance().registerObserver(this);
}
public static AngelObserver getInstance(){
if(instance == null)
instance = new AngelObserver();
return instance;
}
public void setMyIAngelClickLister(IAngelClickLister myIAngelClickLister){
this.myIAngelClickLister = myIAngelClickLister;
}
@Override
public void onClickToUpdate() {
// TODO Auto-generated method stub
myIAngelClickLister.onClickAngelDo();
}
public interface IAngelClickLister{
public void onClickAngelDo();
}
}
(3)ConcreteObserver类-----DevilObserver :
public class DevilObserver implements IClickListernObserver {
private static DevilObserver instance;
private IDevilClickLister myIDevilClickLister;
public DevilObserver(){
ClickListerManager.getInstance().registerObserver(this);
}
public static DevilObserver getInstance(){
if(instance == null)
instance = new DevilObserver();
return instance;
}
public void setMyIDevilClickLister(IDevilClickLister myIDevilClickLister){
this.myIDevilClickLister = myIDevilClickLister;
}
@Override
public void onClickToUpdate() {
// TODO Auto-generated method stub
myIDevilClickLister.onClickDevilDo();
}
public interface IDevilClickLister{
public void onClickDevilDo();
}
}
(4)<<interface>>Subject:
public interface Subject {
public void registerObserver(IClickListernObserver o);
public void unRegisterObserver(IClickListernObserver o);
public void notifyObservers();
}
(5)ConcreteSubject类:
import java.util.ArrayList;
import java.util.List;
public class ClickListerManager implements Subject {
private static ClickListerManager instance;
private List<IClickListernObserver> observers;
public ClickListerManager(){
observers = new ArrayList<IClickListernObserver>();
}
public static ClickListerManager getInstance(){
if(instance == null)
instance = new ClickListerManager();
return instance;
}
public void notifyAllItem(){
notifyObservers();
}
@Override
public void registerObserver(IClickListernObserver object) {
// TODO Auto-generated method stub
if(!observers.contains(object)){
observers.add(object);
}
}
@Override
public void unRegisterObserver(IClickListernObserver object) {
// TODO Auto-generated method stub
if(observers.contains(object)){
observers.remove(object);
}
}
@Override
public void notifyObservers() {
// TODO Auto-generated method stub
for(int i = 0;i < observers.size();i++){
observers.get(i).onClickToUpdate();
}
}
}
(6)ContentObserverActivity类:
import com.example.testcontentobserver01.AngelObserver.IAngelClickLister;
import com.example.testcontentobserver01.DevilObserver.IDevilClickLister;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class ContentObserverActivity extends Activity implements OnClickListener,
IAngelClickLister, IDevilClickLister{
private Button myButton;
private TextView myTextViewAngel;
private TextView myTextViewDevil;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_content_observer);
init();
myButton = (Button) findViewById(R.id.myButton);
myButton.setOnClickListener(this);
myTextViewAngel = (TextView) findViewById(R.id.myTextViewAngel);
myTextViewDevil = (TextView) findViewById(R.id.myTextViewDevil);
}
private void init() {
// TODO Auto-generated method stub
AngelObserver.getInstance();
AngelObserver.getInstance().setMyIAngelClickLister(this);
DevilObserver.getInstance();
DevilObserver.getInstance().setMyIDevilClickLister(this);
}
@Override
public void onClick(View view) {
// TODO Auto-generated method stub
int id = view.getId();
switch(id){
case R.id.myButton:
ClickListerManager.getInstance().notifyAllItem();
}
}
@Override
public void onClickAngelDo() {
// TODO Auto-generated method stub
myTextViewAngel.setText("亲,我是天使,我对于您的点击,我的答复是:我爱你!!");
}
@Override
public void onClickDevilDo() {
// TODO Auto-generated method stub
myTextViewDevil.setText("亲,我是恶魔,我对于您的点击,我的答复是:我恨你!!");
}
}
五:气象监测应用
这个例子也是Head First设计模式(中文版)这本书中的说明样例,这个例子是现在有三个显示装置,一个要显示气象站的温度,一个显示湿度,一个显示气压,并且当这三个数据有改变时,要实时的更新三个显示装置,并且还要方便以后增加显示装置。
解决方案是观察者模式:
(1)类图:
(2)interface Subject:
public interface Subject{
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObservers();
}
(3)interface Observer:
public interface Observer{
public void update(float temp,float humidity,float pressure);
}
(4)interface DisplayElement:
public interface DisplayElement{
public void display();
}
(5)WeatherData 类:
public class WeatherData implements Subject{
private ArrayList observers;
private float temperature;
private float humidity;
private float pressure;
public void registerObserver(Observer o){
observers.add(o);
}
public void removeObserver (Observer o){
int i = observers.indexOf(o);
if(i >= 0){
observers.remove(i);
}
}
public void notifyObservers (){
for(int i = 0; i < observers.size(); i++ ){
Observer observers = (Observer)observers.get(i);
observers.update(temperature, humidity, pressure);
}
}
public void measurementsChanged(){
notifyObservers();
}
public void setMeasurements(float temperature, float humidity, float pressure){
this. temperature = temperature;
this. humidity = humidity;
this. pressure = pressure;
measurementsChanged();
}
………………….
}
(6)类CurrentConditionsDisplay:
public class CurrentConditionsDisplay implements Observer, DisplayElement{
private float temperature;
private float humidity;
private Subject weatherData;
public CurrentConditionsDisplay(Subject weatherData){
this. weatherData = weatherData;
weatherData. registerObserver(this);
}
public void update(float temperature, float humidity, float pressure){
this. temperature = temperature;
this. humidity = humidity;
display();
}
public void display(){
System.out.println(“Current conditions:” + temperature + “F degrees and ” + humidity + “% humidity”);
}
}
(7)相类似的,我们可以实现StatisticsDisplay,ForecastDisplay二个类
省略
(8)测试类:
public class WeatherStation{
public static void main(String[] args){
WeatherData weatherData = new WeatherData();
CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData);
StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData);
ForecastDisplay forecastDisplay = new ForecastDisplay (weatherData);
weatherData. setMeasurements(80,65,30.4f);
weatherData. setMeasurements(70,75,31.4f);
weatherData. setMeasurements(90,55,32.4f);
}
}
参考资料:
1.http://blog.csdn.net/hfreeman2011/article/details/83088732.Head First设计模式(中文版),中国电力出版社出版,O‘REILLY公司译----(39--78页)观察者模式