设计模式(观察者模式)

来源:互联网 发布:开淘宝店自己做模特 编辑:程序博客网 时间:2024/05/04 14:42

观察者模式=发布者+订阅者

Subject.java

public interface Subject{    public void registerObserver(Observer o);    public void removeObserver(Observer o);    public void notifyObservers();}


Observer.java

public interface Observer{   public void update(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 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);}}


这种编码方式不是最好的解决方法,有其他可以改进的N种方法。比如说采用MVC混合模式来设计。而且上面设计的代码 有个弊端就是,当客户端的一个发布站点要更新数据时,服务器端就需要遍历 更新  全部站点的数据并发布,其实只有客户端的数据一个数据变化了,其他的

仍然是原先的状态(值未变),既然值未变,服务端仍用原先值来做下更新的动作,是不是显得多此一举了呢。


下面是改进的一个方法:


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();}}


WeatherStation.java
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!");       }    }}