观察者模式
宋标 Lv5

简介

观察者模式又称发布/订阅模式,用于观察某一个对象产生的变化,发布者无需维护订阅者,订阅者与发布者解耦。
例如生活中,停车位是人们一直苦恼的事情,如果我们能够对车库车位进行实时观察,得到车位信息,是一大便捷的事情。

代码结构

抽象

抽象是为了更好扩展。
抽象出发布者,提供订阅方法供订阅者调用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* 发布者抽象类
* @author songbiao
*/
public abstract class AbstractProducer {

/**
* 订阅
* @param abstractObserver 观察者
* @return 是否订阅成功
*/
public abstract boolean subcribe(AbstractObserver abstractObserver);

/**
* 取消订阅
* @param abstractObserver 观察者
* @return 是否取消订阅成功
*/
public abstract boolean removeSubcribe(AbstractObserver abstractObserver);

}

订阅者抽象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* 订阅者抽象
* @author songbiao
*/
public abstract class AbstractObserver {


/**
* 消息通知
* @param event 消息
*/
public abstract void onEvent(Event event);

}

用于消息通知的事件接口

1
2
3
4
5
6
/**
* @author songbiao
*/
public interface Event {

}

实现

车辆实体类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Car {

private int id;
private String info;

public Car(int id, String info) {
this.id = id;
this.info = info;
}
@Override
public String toString() {
return "Car{" +
"id=" + id +
", info='" + info + '\'' +
'}';
}
}

车辆通知事件,实现Event接口,用于事件通知。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class CarEvent implements Event{

private Car curCarInfo;
private String type;

public Car getCurCarInfo() {
return curCarInfo;
}

public String getType() {
return type;
}

public CarEvent(Car curCarInfo, String type) {
this.curCarInfo = curCarInfo;
this.type = type;
}

@Override
public String toString() {
return "CarEvent{" +
"curCarInfo=" + curCarInfo +
", type=" + type +
'}';
}
}

发布者实现(车库),实现AbstractProducer抽象类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/**
* 车库订阅发现实现
*/
public class Garage extends AbstractProducer {

/**
* 订阅集合
*/
private List<AbstractObserver> subcriberList = new ArrayList<>();
/**
* 车辆停放集合
*/
private List<Car> parkList = new ArrayList<>();


@Override
public boolean subcribe(AbstractObserver observer) {
return subcriberList.add(observer);
}

@Override
public boolean removeSubcribe(AbstractObserver observer) {
return subcriberList.remove(observer);
}

/**
* 车辆离开
* @param car 车辆
*/
public void carLeave(Car car) {
parkList.remove(car);
final Event event = new CarEvent(car,"车辆离开");
subcriberList.parallelStream().forEach(observer -> {
observer.onEvent(event);
});
}

/**
* 车辆进入
* @param car 车辆
*/
public void enterCar(Car car){
parkList.add(car);
final Event event = new CarEvent(car,"车辆进入");
subcriberList.parallelStream().forEach(observer -> {
observer.onEvent(event);
});
}

}

车库订阅者通知实现类,实现AbstractObserver抽象类

1
2
3
4
5
6
7
8
9
public class CarObserver extends AbstractObserver {

@Override
public void onEvent(Event event) {
//打印车库事件消息
System.out.println(event);
}
}

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static void main(String[] args) {
//创建一个车库观察者
CarObserver carObserver = new CarObserver();
//被观察者
Garage garage = new Garage();

//添加观察者
garage.subcribe(carObserver);

//测试
Car fa = new Car(1, "法拉利");
Car lb = new Car(2, "兰博基尼");

garage.enterCar(fa);
garage.enterCar(lb);
garage.carLeave(lb);
garage.carLeave(fa);
}

测试结果:

1
2
3
4
CarEvent{curCarInfo=Car{id=1, info='法拉利'}, type=车辆进入}
CarEvent{curCarInfo=Car{id=2, info='兰博基尼'}, type=车辆进入}
CarEvent{curCarInfo=Car{id=2, info='兰博基尼'}, type=车辆离开}
CarEvent{curCarInfo=Car{id=1, info='法拉利'}, type=车辆离开}
 评论