1. 模式
定义:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新
分类:行为型模式
2. 任务
- 现存在一个红绿灯和 M 个车辆,实现红灯停,绿灯行,黄灯亮了等一等。
- 现在增加警车,在遇到红灯也可以行走。
- 分别以推模式和拉模式实现。在推模式中,红灯变化会通知所有车辆(简单,但对红绿灯不友好),拉模式中车辆会定期查看红绿灯。
3. JS 实现
3.1. 推模式
class Light {
constructor() {
this._currentState = -1; // ['红', '绿', '黄']
this._observers = new Set();
}
getState() {
return this._currentState;
}
setState(state) {
if (state < 0 || state > 2) {
return false;
}
if (this._currentState === state) {
return false;
}
this._currentState = state;
const iterator = this._observers.entries();
for (let entry of iterator) {
entry[0].update(this._currentState);
}
}
subscrib(observer) {
this._observers.add(observer);
}
unSubscrib(observer) {
if (this._observers.has(observer)) {
this._observers.delete(observer);
}
}
}
class Car {
constructor() {}
update(data) {
this.processLight(data);
}
processLight(lightstate) {
//红灯停,绿灯行,黄灯亮了等一等
if (lightstate === 0) {
console.log(`红灯停`);
} else if (lightstate === 1) {
console.log(`绿灯行`);
} else {
console.log(`黄灯亮了等一等`);
}
}
}
const light_1 = new Light();
const car_1 = new Car();
light_1.subscrib(car_1);
light_1.setState(0);
light_1.setState(1);
light_1.setState(2);
light_1.unSubscrib(car_1);
light_1.setState(1);
light_1.setState(2);
3.2. 拉模式
class Light {
constructor() {
this._currentState = -1; // ['红', '绿', '黄']
}
getState() {
return this._currentState;
}
setState(state) {
if (state < 0 || state > 2) {
return false;
}
if (this._currentState === state) {
return false;
}
this._currentState = state;
}
}
class Car {
constructor() {
this._subjects = new Set();
}
pull() {
const iterator = this._subjects.entries();
for (let entry of iterator) {
let data = entry[0].getState();
this.processLight(data);
}
}
subscrib(subject) {
this._subjects.add(subject);
}
unSubscrib(subject) {
if (this._subjects.has(subject)) {
this._subjects.delete(subject);
}
}
processLight(lightstate) {
//红灯停,绿灯行,黄灯亮了等一等
if (lightstate === 0) {
console.log(`红灯停`);
} else if (lightstate === 1) {
console.log(`绿灯行`);
} else {
console.log(`黄灯亮了等一等`);
}
}
}
const light_1 = new Light();
const car_1 = new Car();
const car_2 = new Car();
car_1.subscrib(light_1);
car_2.subscrib(light_1);
car_1.pull();
car_2.pull();