设计模式(观察者模式)

傷城~ 2022-10-15 12:00 106阅读 0赞

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

Subject.java

  1. public interface Subject{
  2. public void registerObserver(Observer o);
  3. public void removeObserver(Observer o);
  4. public void notifyObservers();
  5. }

Observer.java

  1. public interface Observer{
  2. public void update(float temp,float humidity,float pressure);
  3. }

DisplayElement.java

  1. public interface DisplayElement{
  2. public void display();
  3. }

WeatherData.java

  1. import java.util.ArrayList;
  2. public class WeatherData implements Subject{
  3. private ArrayList observers;
  4. private float temperature;
  5. private float humidity;
  6. private float pressure;
  7. public WeatherData(){
  8. observers = new ArrayList();
  9. }
  10. public void registerObserver(Observer o){
  11. observers.add(o);
  12. }
  13. public void removeObserver(Observer o){
  14. int i=observers.indexOf(o);
  15. if(i>=0){
  16. observers.remove(i);
  17. }
  18. }
  19. public void notifyObservers(){
  20. for(int i=0;i<observers.size();i++){
  21. Observer observer=(Observer)observers.get(i);
  22. observer.update(temperature,humidity,pressure);
  23. }
  24. }
  25. public void measurementsChanged(){
  26. notifyObservers();
  27. }
  28. public void setMeasurements(float temperature,float humidity,float pressure){
  29. this.temperature = temperature;
  30. this.humidity = humidity;
  31. this.pressure = pressure;
  32. measurementsChanged();
  33. }
  34. }

CurrentConditionDisplay.java

  1. import java.io.*;
  2. public class CurrentConditionsDisplay implements Observer ,DisplayElement{
  3. private float temperature;
  4. private float humidity;
  5. private WeatherData weatherData;
  6. public CurrentConditionsDisplay(WeatherData weatherData_){
  7. this.weatherData= weatherData_;
  8. weatherData.registerObserver(this);
  9. }
  10. public void update(float temperature,float humidity,float pressure){
  11. this.temperature = temperature;
  12. this.humidity = humidity;
  13. display();
  14. }
  15. public void display(){
  16. System.out.println("Current condition :"+temperature+" F degrees and "+ humidity + "%humidity");
  17. }
  18. }

WeatherStation.java

  1. public class WeatherStation{
  2. public static void main(String[] args){
  3. WeatherData weatherData = new WeatherData();
  4. CurrentConditionsDisplay currentDisplay= new CurrentConditionsDisplay(weatherData);
  5. weatherData.setMeasurements(80,65,30.4f);
  6. }
  7. }

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

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

下面是改进的一个方法:

Subject.java

  1. public interface Subject{
  2. public void registerObserver(Observer o);
  3. public void removeObserver(Observer o);
  4. }

Observer.java

  1. public interface Observer{
  2. public void _setM(float temp,float humidity,float pressure);
  3. }

DisplayElement.java

  1. public interface DisplayElement{
  2. public void display();
  3. }

WeatherData.java

  1. import java.util.ArrayList;
  2. public class WeatherData implements Subject{
  3. private ArrayList observers;
  4. private float temperature;
  5. private float humidity;
  6. private float pressure;
  7. public WeatherData(){
  8. observers = new ArrayList();
  9. }
  10. public void registerObserver(Observer o){
  11. observers.add(o);
  12. }
  13. public void removeObserver(Observer o){
  14. int i=observers.indexOf(o);
  15. if(i>=0){
  16. observers.remove(i);
  17. }
  18. }
  19. public void display(){
  20. System.out.println("Current condition :"+temperature+" F degrees and "+ humidity + "%humidity");
  21. }
  22. public void setMeasurements(float temperature,float humidity,float pressure){
  23. this.temperature = temperature;
  24. this.humidity = humidity;
  25. this.pressure = pressure;
  26. }
  27. }

CurrentConditionDisplay.java

  1. import java.io.*;
  2. public class CurrentConditionsDisplay implements Observer ,DisplayElement{
  3. private float temperature;
  4. private float humidity;
  5. private WeatherData weatherData;
  6. public CurrentConditionsDisplay(WeatherData weatherData_){
  7. this.weatherData= weatherData_;
  8. weatherData.registerObserver(this);
  9. }
  10. public void _setM(float temperature,float humidity,float pressure){
  11. weatherData.setMeasurements(temperature,humidity,pressure);
  12. }
  13. public void display(){
  14. weatherData.display();
  15. }
  16. }

WeatherStation.java

  1. public class WeatherStation{
  2. public static void main(String[] args){
  3. WeatherData weatherData = new WeatherData();
  4. CurrentConditionsDisplay currentDisplay= new CurrentConditionsDisplay(weatherData);
  5. currentDisplay._setM(80,65,30.4f);
  6. currentDisplay.display();
  7. }
  8. }

当然,以上阐述有个bug,因为观察者模式就是默认通知所有“订阅者”的。根据需要来设计了。

内部类一例:

  1. public class SwingObserverExample {
  2. JFrame frame;
  3. public static void main(String[] args) {
  4. SwingObserverExample example = new SwingObserverExample();
  5. example.go();
  6. }
  7. public void go() {
  8. frame = new JFrame();
  9. JButton button = new JButton("Should I do it?");
  10. button.addActionListener(new AngelListener());
  11. button.addActionListener(new DevilListener());
  12. frame.getContentPane().add(BorderLayout.CENTER, button);
  13. // 在这里设置frame属性
  14. }
  15. class AngelListener implements ActionListener {
  16. public void actionPerformed(ActionEvent event) {
  17. System.out.println("Don't do it, you might regret it!");
  18. }
  19. }
  20. class DevilListener implements ActionListener {
  21. public void actionPerformed(ActionEvent event) {
  22. System.out.println("Come on, do it!");
  23. }
  24. }
  25. }

发表评论

表情:
评论列表 (有 0 条评论,106人围观)

还没有评论,来说两句吧...

相关阅读

    相关 设计模式-观察模式

    观察者模式 引言 > 今天开车出去有事,还挺赶时间的,突然遇到了一个红灯,这红灯时间可真长,等了好久终于看到变绿灯了,赶紧开车过去。 正文 观察者模式是指多

    相关 设计模式-观察模式

    观察者模式也叫订阅发布模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

    相关 设计模式——观察模式

      观察者模式——定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态发生改变时,会通知所有观察者对象,使它们能够自动更新自己。   观察者

    相关 设计模式:观察模式

    一.简介 > QT的信号槽就是观察者模式,当事件发生之后(比如按钮被点击)就会发出一个信号,这种信号类似广播没有目的.当对象对信号感兴趣,就会通过 connect() 函

    相关 设计模式--观察模式

    定义 在对象之间定义了一对多的依赖,当一方发生改变时,依赖它的对象都会受到通知并自动更新。 其实可以理解为消息发布者(被观察者)与订阅者(观察者),用户可以订阅或者取消