观察者模式-气象台的实现与应用

本文介绍了观察者模式的典型实现步骤,包括定义观察者和被观察者接口,实现接口的类,以及如何注册和通知观察者。通过具体的气象台场景,展示了观察者模式在实际业务逻辑中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

观察者模式典型实现方式:
1、定义2个接口:观察者(通知)接口、被观察者(主题)接口
2、定义2个类,观察者对象实现观察者接口、主题类实现被观者接口
3、主题类注册自己需要通知的观察者
4、主题类某个业务逻辑发生时通知观察者对象,每个观察者执行自己的业务逻辑。

类图


参考代码

package org.test.Observer;

public interface Observer {
	/**
	 * 观察者类
	 * @param temp
	 * @param humidity
	 * @param pressure
	 */
	void update(float temp,float humidity,float pressure);
}


package org.test.Observer;
//被观察者-主题公园类..名字应该改下,,不过人懒
public interface Subject {
	void removeObserver(Observer observer);
	void addObserver(Observer observer);
	void notifyObserver();
}

package org.test.Observer;
//display
public interface DisplayElement {
	void display();
}

package org.test.Observer;
//天气数据中心-被观察者的实现类
import java.util.ArrayList;
import java.util.List;

public class WeatherData implements Subject {

	private final List<Observer> lObserver = new ArrayList<Observer>();
	private float temperature;
	private float humidity;
	private float pressure;
//	java.util.Observer
	@Override
	public void removeObserver(Observer observer) {
//		lObserver.remove(observer);
		int i = lObserver.indexOf(observer);
		if (i>=0){
			lObserver.remove(i);
		}else{
			System.out.println("empty list");
		}
		
	}

	@Override
	public void addObserver(Observer observer) {
		lObserver.add(observer);
	}

	@Override
	public void notifyObserver() {
		for(Observer o:lObserver){
			o.update(temperature, humidity, pressure);
		}
	}

	public void setMeasurements(float temperature, float humidity, float pressure) {
		//super();
		this.temperature = temperature;
		this.humidity = humidity;
		this.pressure = pressure;
		measurementsChanged();
	}

	private void measurementsChanged() {
		notifyObserver();
	} 
	
	
	//others


}

package org.test.Observer;
//观察者实现类,current

public class CurrentConditionsDisplay implements Observer, DisplayElement {

	private float temperature;
	private float humidity;
	private Subject weatherData;

	public CurrentConditionsDisplay(Subject weatherData) {
		this.weatherData = weatherData;
		weatherData.addObserver(this);//加入消息收听队列
	}

	@Override
	public void display() {
		System.out.println("current conditions:" + temperature + "F degrees and " + humidity + "% humidity");
	}

	@Override
	public void update(float temp, float humidity, float pressure) {
		this.temperature = temp;
		this.humidity = humidity;
		display();
	}

}

package org.test.Observer;
//观察者实现类
public class StatisticsDisplay implements Observer, DisplayElement {
	
	private float temperature;
	private float humidity;
	private Subject weatherData;
	

	public StatisticsDisplay(Subject weatherData) {
		this.weatherData = weatherData;
		weatherData.addObserver(this);
	}

	@Override
	public void display() {
		System.out.println("statistice conditions:" + temperature + "F degrees and " + humidity + "% humidity");
	}

	@Override
	public void update(float temp, float humidity, float pressure) {
		this.temperature = temp;
		this.humidity = humidity;
		display();
	}


}

package org.test.Observer;
//main
public class WeatherStation {
	public static void main(String[] args) {
		WeatherData weatherData = new WeatherData();
		CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData);
		StatisticsDisplay statisDisplay = new StatisticsDisplay(weatherData);
		weatherData.setMeasurements(80, 12, 30.4f);
		weatherData.setMeasurements(70, 45, 45f);
		
	}
}



JDK自带观察者模式

java.util.Observer观察者接口

package java.util;

/**
 * A class can implement the <code>Observer</code> interface when it
 * wants to be informed of changes in observable objects.
 *
 * @author  Chris Warth
 * @see     java.util.Observable
 * @since   JDK1.0
 */
public interface Observer {
    /**
     * This method is called whenever the observed object is changed. An
     * application calls an <tt>Observable</tt> object's
     * <code>notifyObservers</code> method to have all the object's
     * observers notified of the change.
     *
     * @param   o     the observable object.
     * @param   arg   an argument passed to the <code>notifyObservers</code>
     *                 method.
     */
    void update(Observable o, Object arg);
}


java.util.Observable被观察者具体类

package java.util;

public class Observable {
    private boolean changed = false;
    private Vector obs;

        public Observable() {
        obs = new Vector();
    }

    
    public synchronized void addObserver(Observer o) {
        if (o == null)
            throw new NullPointerException();
        if (!obs.contains(o)) {
            obs.addElement(o);
        }
    }

    
    public synchronized void deleteObserver(Observer o) {
        obs.removeElement(o);
    }
    public void notifyObservers() {
        notifyObservers(null);
    }

    
    public void notifyObservers(Object arg) {
        Object[] arrLocal;

        synchronized (this) {
            /* We don't want the Observer doing callbacks into
             * arbitrary code while holding its own Monitor.
             * The code where we extract each Observable from
             * the Vector and store the state of the Observer
             * needs synchronization, but notifying observers
             * does not (should not).  The worst result of any
             * potential race-condition here is that:
             * 1) a newly-added Observer will miss a
             *   notification in progress
             * 2) a recently unregistered Observer will be
             *   wrongly notified when it doesn't care
             */
            if (!changed)
                return;
            arrLocal = obs.toArray();
            clearChanged();
        }

        for (int i = arrLocal.length-1; i>=0; i--)
            ((Observer)arrLocal[i]).update(this, arg);
    }

    
    public synchronized void deleteObservers() {
        obs.removeAllElements();
    }

   
    protected synchronized void setChanged() {
        changed = true;
    }

    
    protected synchronized void clearChanged() {
        changed = false;
    }

   
    public synchronized boolean hasChanged() {
        return changed;
    }

   
    public synchronized int countObservers() {
        return obs.size();
    }
}


测试Demo

package org.test.Observer.ByJdk;
//图文信息对象
import java.util.Observable;
import java.util.Observer;

public class PicMessage extends Observable {

	private String title = "";
	private double size = 0.0;
	public String getTitle() {
		return title;
	}
	public double getSize() {
		return size;
	}
	public void updateMessage(String title,double size){
		this.title =title;
		this.size = size;
	}
	
	public void subscription(Observer o){
		addObserver(o);
	}
	
	public void modifyPrice(PicMessage pm){
		setChanged();
		notifyObservers(pm);
	}
	
}


package org.test.Observer.ByJdk;
//观察者手机端
import java.util.Observable;
import java.util.Observer;

public class PhoneLogon implements Observer {
	
	private String username = "";

	public PhoneLogon(String username) {
		this.username = username;
	}
	@Override
	public void update(Observable o, Object arg) {
		// TODO Auto-generated method stub
		PicMessage pm = (PicMessage)arg;
		System.out.println(username+"在手机登陆,点击查看《"+pm.getTitle()+"》,信息长度:"+pm.getSize());
	}

}

package org.test.Observer.ByJdk;
//观察者PC端
import java.util.Observable;
import java.util.Observer;

public class PCLogon implements Observer {
	private String username = "";
	public PCLogon(String username) {
		this.username = username;
	}

	@Override
	public void update(Observable o, Object arg) {
		// TODO Auto-generated method stub
		PicMessage pm = (PicMessage)arg;
		System.out.println(username+"在电脑登陆,点击查看《"+pm.getTitle()+"》图文信息,长度:"+pm.getSize());
	}

}

package org.test.Observer.ByJdk;
//测试代码
import java.util.Observer;

public class Demo {
	public static void main(String[] args) throws InterruptedException {
		PicMessage pm = new PicMessage();
		pm.updateMessage("我们公司上市了", 5.0);
		pm.subscription(new PCLogon("haoren"));
		pm.subscription(new PCLogon("huairen"));
		pm.subscription(new PhoneLogon("haoren"));
		pm.modifyPrice(pm);
	}
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值