• 设计模式(十七)Observer模式


      在Observer模式中,当观察对象的状态发生变化时,会通知给观察者。Observer模式适用于根据对象状态进行相应处理的场景。

      首先看一下示例程序的视图。

     

      然后用实际代码来理解这种设计模式。

    1 package bigjunoba.bjtu.observer;
    2 
    3 public interface Observer {
    4 
    5     public abstract void update(NumberGenerator generator);
    6 }

      Observer接口是用来表示“观察者”的接口。具体的观察者会实现这个接口。用于生成数值的NumberGenerator类会调用update方法。如果调用update方法,NumberGenerator类就会将“生成的数值发生了变化,请更新显示内容”的通知发送给Observer。

     1 package bigjunoba.bjtu.observer;
     2 
     3 import java.util.ArrayList;
     4 import java.util.Iterator;
     5 
     6 public abstract class NumberGenerator {
     7 
     8     private ArrayList<Observer> observers = new ArrayList<>();
     9     
    10     public void addObserver(Observer observer) {
    11         observers.add(observer);
    12     }
    13     
    14     public void deleteObserver(Observer observer) {
    15         observers.remove(observer);
    16     }
    17     
    18     public void notifyObservers() {
    19         Iterator<Observer> iterator = observers.iterator();
    20         while (iterator.hasNext()) {
    21             Observer observer = (Observer) iterator.next();
    22             observer.update(this);
    23         }
    24     }
    25     
    26     public abstract int getNumber();
    27     public abstract void excute();
    28 
    29 }

      NumberGenerator类是用于生成数值的抽象类。生成数值的excute方法和获取数值的getNumber方法都是抽象方法,需要子类去实现。observers字段中保存有观察NumberGenerator的Observer们。notifyObservers方法会向所有的Observer发送通知,告诉他们“我生成的数值发生了变化,请更新显示内容”。该方法会调用每个Observer的update方法。

     1 package bigjunoba.bjtu.observer;
     2 
     3 import java.util.Random;
     4 
     5 public class RandomNumberGenetor extends NumberGenerator {
     6     
     7     private Random random = new Random();
     8     private int number;
     9     
    10     @Override
    11     public int getNumber() {
    12         return number;
    13     }
    14 
    15     @Override
    16     public void excute() {
    17         for (int i = 0; i < 10; i++) {
    18             number = random.nextInt(50);
    19             notifyObservers();
    20         }
    21     }
    22 }

      RandomNumberGenetor类是NumberGenerator的子类。excute方法会生成10个随机数,并通过notifyObservers方法把每次生成的结果通知给观察者。

     1 package bigjunoba.bjtu.observer;
     2 
     3 public class DigitObserver implements Observer {
     4 
     5     @Override
     6     public void update(NumberGenerator generator) {
     7         System.out.println("DigitObserver:" + generator.getNumber());
     8         try {
     9             Thread.sleep(100);
    10         } catch (InterruptedException e) {
    11         }
    12     }
    13 }

      DigitObserver类作为第一个观察者,它的功能是以数字形式显示观察到的数值。为了能看清它是如何显示数值的,使用Thread.sleep(100)来降低程序的运行速度。

     1 package bigjunoba.bjtu.observer;
     2 
     3 public class GraphObserver implements Observer {
     4 
     5     @Override
     6     public void update(NumberGenerator generator) {
     7         System.out.println("GraphObserver:");
     8         
     9         int count = generator.getNumber();
    10         for (int i = 0; i < count; i++) {
    11             System.out.print("*");
    12         }
    13         
    14         System.out.println("");
    15         
    16         try {
    17             Thread.sleep(100);
    18         } catch (InterruptedException e) {
    19         }
    20     }
    21 }

      GraphObserver类作为第二个观察者,功能是将观察到的数值以****表示出来。

     1 package bigjunoba.bjtu.observer;
     2 
     3 public class Main {
     4     public static void main(String[] args) {
     5         NumberGenerator generator = new RandomNumberGenetor();
     6         Observer observer1 = new DigitObserver();
     7         Observer observer2 = new GraphObserver();
     8         generator.addObserver(observer1);
     9         generator.addObserver(observer2);
    10         generator.excute();
    11     }
    12 }

      Main类作为测试类。首先生成了RandomNumberGenerator类的实例保存在NumberGenerator类的generator字段中,然后生成两个观察者实例,然后将观察者注册之后,调用每一个观察者的update方法。

    DigitObserver:20
    GraphObserver:
    ********************
    DigitObserver:46
    GraphObserver:
    **********************************************
    DigitObserver:10
    GraphObserver:
    **********
    DigitObserver:45
    GraphObserver:
    *********************************************
    DigitObserver:10
    GraphObserver:
    **********
    DigitObserver:5
    GraphObserver:
    *****
    DigitObserver:37
    GraphObserver:
    *************************************
    DigitObserver:24
    GraphObserver:
    ************************
    DigitObserver:34
    GraphObserver:
    **********************************
    DigitObserver:30
    GraphObserver:
    ******************************
    

       测试结果如上图所示。

      这里不作过多解释。因为这种设计模式还是很容易理解的。

  • 相关阅读:
    JTAG的SWD接线方式
    Qt のEXecl
    人脸识别
    Qt实现基本QMainWindow主窗口程序
    Qt学习之路MainWindow学习过程中的知识点
    QT_FORWARD_DECLARE_CLASS
    标准的并发控制实现
    C++ DFS
    C# 互操作(一) 编写一个C++ COM组件
    Socket使用SOAP调用WCF
  • 原文地址:https://www.cnblogs.com/BigJunOba/p/8804878.html
Copyright © 2020-2023  润新知