观察者模式指的是当存在一对多的场景的时候,一个对象发生了状态的变化之后,多个对象能够得到通知并且获得更新。
这个模式在一些pub/sub方式的中间件中很常见,例如消息的发布与订阅,MQTT的pub与sub。
但是如果真正的比较起来,跟pub/sub方式会存在一些区别,pub/sub的方式中,生产者和消费者中间还有一个broker,也就是说生产者和消费者之间是互相不知道的,生产者只负责生产数据给broker,而消费者只管去broker取数据。观察者模式的话,生产者在产生数据的时候,是会直接通知到消费者的
对于其中的产生变化的对象,我们可以把它称为生产者,而关注变化的对象,我们称为消费者。
在实际的场景中,该设计模式也是很常见。例如我们有 有一个服务是负责库存的,有好几个服务是会依赖库存的数据的,当库存产生数据的时候,他们需要被通知到,并且进行自己的业务处理。
 
java实现
在下面,我们会实现一个最简单的观察者模式的代码示例。主要包含三个文件,一个生产者,一个消费者以及一个测试类。
消费者
1 2 3 4 5 6 7 8 9 10 11 12 13 14
   | public class ObserverDemo {     private String value;          public void callback(String result)     {         System.out.println(result + "  " + value);     }          public ObserverDemo(String value)     {         this.value = value;     } }
   | 
 
我们在消费者里面实现一个callback方法,用来接收生产者发生变化的回调。
生产者
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
   | public class ProducerDemo {          private static Set<ObserverDemo> observerDemos = new HashSet<>();          private final static List<String> DAY = Arrays.asList("today", "tomorrow", "yesterday");          public static void addObserver(ObserverDemo observerDemo)     {         observerDemos.add(observerDemo);     }          public static void startProduce() throws InterruptedException     {         while (true)         {             String result = DAY.get(new Random().nextInt(DAY.size()));             observerDemos.forEach(o -> o.callback(result));             Thread.sleep(2000);         }        } }
   | 
 
- 这里我们用一个set,存储所有的消费者。
 
- 当生产数据的时候,我们会通过调用消费者的callback函数,来实现对他们的通知。
 
测试代码
1 2 3 4 5 6 7 8
   | public static void main(String[] args) throws Exception     {         ObserverDemo o1 = new ObserverDemo("morning");         ObserverDemo o2 = new ObserverDemo("afternoon");         ProducerDemo.addObserver(o1);         ProducerDemo.addObserver(o2);         ProducerDemo.startProduce();     }
   | 
 
- 这里我们新建两个消费者,通过赋予不同的值,来进行区分。
 
- 然后我们调用生产者的生产函数,来观察输出
 
结果

我们通过将观察者加入到生产者的通知队列中,然后在生产数据的时候,调用观察者的对应的回调函数,进而就不需要关心观察者的具体实现细节,并且实现了通知的功能,完成了代码之间的解耦。