IOTXING

记录技术学习之路

0%

java设计模式-观察者模式

观察者模式指的是当存在一对多的场景的时候,一个对象发生了状态的变化之后,多个对象能够得到通知并且获得更新。

这个模式在一些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();
}
  • 这里我们新建两个消费者,通过赋予不同的值,来进行区分。
  • 然后我们调用生产者的生产函数,来观察输出

结果

https://iotxing-1253163150.cos.ap-shanghai.myqcloud.com/%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F.jpg

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