设计模式(一)观察者模式

介绍

Observer method

如图,观察者模式涉及到两种对象,Observer和Subject(Observable)。

Subject(Observable) 是可观察的对象,而Observer则是观察者,使用流程一般是:

  1. Observer将自己注册到对应的Subject中
  2. Subject的状态变化时,遍历已注册的观察者列表,逐一调用观察者的update方法

其中主要的逻辑在观察者的update方法中,其通过分析Subject更新的信息来执行一定的操作。

实例

观察者模式也叫发布-订阅模式。

事件监听器就是使用的这一模式。

Minecraft 监听玩家遭受攻击的事件

在Minecraft(一款沙盒游戏)中,所有的游戏对象更新时都会触发相应的事件,在服务端中,开发者可以通过编写插件来监听事件并修改一些参数来实现特定的功能。

举例来说,玩家遭受怪物的攻击,血量会下降,这一事件是EntityDamageByEntityEvent,这里我想让玩家免受伤害。

1
2
3
4
5
6
7
//插件示例,仅包含核心代码
@EventHandler
public void onDamage(EntityDamageByEntityEvent evt) {
if(evt.getEntity() instanceof Player) {
evt.setDamage(0D);
}
}

这里通过注解EventHandler将该方法注册到事件EntityDamageByEntityEvent的监听器列表中,当玩家受到伤害时,onDamage方法被调用,该事件的最终伤害会设置为0,因此玩家在这个事件发生后不会掉血。

在这里用到观察者模式有什么好处呢?

  1. 根据特定事件更改游戏状态,但不需要修改服务端;
  2. 多个开发者的多个插件都可以通过这种方式把自己的事件监听器注册到服务端中,互相不影响;
  3. 对于服务端来说,它在运行时才知道最终要调用的事件监听器有哪些,而且这些都是动态的。

JavaScript 监听表单提交的事件

Minecraft是个人之前玩过的游戏,这里再举一个Web开发的例子。

Reference: GlobalEventHandlers.onsubmit

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//函数
<script>
const form = document.getElementById('form');
form.onsubmit = submit;

function submit(evt) {
evt.preventDefault();
}
</script>
//视图
<form id="form">
Enter name: <input type="text">
<input type="submit">
</form>

结果就是这个页面的表单是没办法正常提交的。