观察者模式=发布者+订阅者
Subject.java
public interface Subject{ public void registerObserver(Observer o); public void removeObserver(Observer o); public void notifyObservers(); }
public interface Observer{ public void update(float temp,float humidity,float pressure); }
DisplayElement.java
public interface DisplayElement{ public void display(); }
import java.util.ArrayList; public class WeatherData implements Subject{ private ArrayList observers; private float temperature; private float humidity; private float pressure; public WeatherData(){ observers = new ArrayList(); } 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 observer=(Observer)observers.get(i); observer.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(); } }
CurrentConditionDisplay.java
import java.io.*; public class CurrentConditionsDisplay implements Observer ,DisplayElement{ private float temperature; private float humidity; private WeatherData weatherData; public CurrentConditionsDisplay(WeatherData 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 condition :"+temperature+" F degrees and "+ humidity + "%humidity"); } }
WeatherStation.java
public class WeatherStation{ public static void main(String[] args){ WeatherData weatherData = new WeatherData(); CurrentConditionsDisplay currentDisplay= new CurrentConditionsDisplay(weatherData); weatherData.setMeasurements(80,65,30.4f); } }
仍然是原先的状态(值未变),既然值未变,服务端仍用原先值来做下更新的动作,是不是显得多此一举了呢。
下面是改进的一个方法:
Subject.java
public interface Subject{ public void registerObserver(Observer o); public void removeObserver(Observer o); }
Observer.java
public interface Observer{ public void _setM(float temp,float humidity,float pressure); }
DisplayElement.java
public interface DisplayElement{ public void display(); }
WeatherData.java
import java.util.ArrayList; public class WeatherData implements Subject{ private ArrayList observers; private float temperature; private float humidity; private float pressure; public WeatherData(){ observers = new ArrayList(); } 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 display(){ System.out.println("Current condition :"+temperature+" F degrees and "+ humidity + "%humidity"); } public void setMeasurements(float temperature,float humidity,float pressure){ this.temperature = temperature; this.humidity = humidity; this.pressure = pressure; } }
CurrentConditionDisplay.java
import java.io.*; public class CurrentConditionsDisplay implements Observer ,DisplayElement{ private float temperature; private float humidity; private WeatherData weatherData; public CurrentConditionsDisplay(WeatherData weatherData_){ this.weatherData= weatherData_; weatherData.registerObserver(this); } public void _setM(float temperature,float humidity,float pressure){ weatherData.setMeasurements(temperature,humidity,pressure); } public void display(){ weatherData.display(); } }
public class WeatherStation{ public static void main(String[] args){ WeatherData weatherData = new WeatherData(); CurrentConditionsDisplay currentDisplay= new CurrentConditionsDisplay(weatherData); currentDisplay._setM(80,65,30.4f); currentDisplay.display(); } }
当然,以上阐述有个bug,因为观察者模式就是默认通知所有“订阅者”的。根据需要来设计了。
内部类一例:
public class SwingObserverExample { JFrame frame; public static void main(String[] args) { SwingObserverExample example = new SwingObserverExample(); example.go(); } public void go() { frame = new JFrame(); JButton button = new JButton("Should I do it?"); button.addActionListener(new AngelListener()); button.addActionListener(new DevilListener()); frame.getContentPane().add(BorderLayout.CENTER, button); // 在这里设置frame属性 } class AngelListener implements ActionListener { public void actionPerformed(ActionEvent event) { System.out.println("Don't do it, you might regret it!"); } } class DevilListener implements ActionListener { public void actionPerformed(ActionEvent event) { System.out.println("Come on, do it!"); } } }