import java.util.ArrayList;
import java.util.List;
/**
* 观察者模式模拟当地震来临时,狗狗叫,居民跑,房子塌的场景
* 地震事件有三个属性,位置,耗时,强度
* 当位置赋值后,则就发生了地震,狗狗就会叫
* 当位置赋值,且耗时超过5秒,居民才会跑
* 当位置赋值,耗时超过5秒,且强度大于6的强度,房子才会塌
*/
public class ObserverMode {
public static void main(String[] args) {
EathquakeHappen eathquakeHappen = new EathquakeHappen();
System.out.println("-----------------模拟只会狗狗叫---------------");
eathquakeHappen.quake(100, 1, 1);
System.out.println("-----------------模拟狗狗叫,居民跑--------------");
eathquakeHappen.quake(100, 6, 1);
System.out.println("-----------------模拟狗狗叫,居民跑,房子塌--------------");
eathquakeHappen.quake(100, 6, 7);
}
}
/*
地震发生时
*/
class EathquakeHappen{
List<Observer> observerList = new ArrayList<>();
// 这样就可以动态在配置文件中配置观察者,不用与代码融合
{
observerList.add(new Dog());
observerList.add(new Citizen());
observerList.add(new House());
}
public void quake(int loc, int duration, int strength){
Event earthquakeEvent = new EarthquakeEvent(loc, duration, strength);
for (Observer observer : observerList){
observer.doSomething(earthquakeEvent);
}
}
}
/*
事件源本身,记录了地震的位置、耗时、强度
*/
class Eathquake{
// 这三个参数,为0时默认没有赋值
private int loc; // 位置
private int duration; // 耗时
private int strength; // 强度
public Eathquake(int loc, int duration, int strength) {
this.loc = loc;
this.duration = duration;
this.strength = strength;
}
public int getLoc() {
return loc;
}
public int getDuration() {
return duration;
}
public int getStrength() {
return strength;
}
}
/*
事件的接口,泛型为事件源本身
*/
interface Event<T>{
// 此方法用于返回事件源本身
T getSource();
}
/*
地震事件,实现事件接口,事件源是地震
*/
class EarthquakeEvent implements Event<Eathquake>{
Eathquake eathquake;
// 返回事件本身
@Override
public Eathquake getSource() {
return eathquake;
}
// 地震事件的构造方法,当发生地震时,记录位置、耗时、强度
public EarthquakeEvent(int loc, int duration, int strength){
eathquake = new Eathquake(loc, duration, strength);
}
}
/*
观察者的接口,方法为地震时各个人做的事情
*/
interface Observer{
void doSomething(Event event);
}
class Dog implements Observer{
@Override
public void doSomething(Event event) {
// 第一层判断模拟狗狗并不是只有地震的时候才叫,根据不通来源,叫的方式不同,所以判断来源
if (event != null && event.getSource() instanceof Eathquake){
Eathquake earthquake = (Eathquake) event.getSource();
// 当位置赋值后,则就发生了地震,狗狗就会叫
if (earthquake.getLoc() > 0){
System.out.println("狗狗叫:call~");
}
} else {
System.out.println("狗狗叫,其他来源");
}
}
}
class Citizen implements Observer{
@Override
public void doSomething(Event event) {
// 第一层判断模拟居民并不是做跑这一件事,根据不通来源,处理方式不同,所以判断来源
if (event != null && event.getSource() instanceof Eathquake){
Eathquake earthquake = (Eathquake) event.getSource();
// 当位置赋值,且耗时超过5秒,居民才会跑
if (earthquake.getLoc() > 0 && earthquake.getDuration() > 5){
System.out.println("居民跑:run~");
}
} else {
System.out.println("居民做其他的事情");
}
}
}
class House implements Observer{
@Override
public void doSomething(Event event) {
// 第一层判断模拟房子的状态,根据不通来源,状态不同,所以判断来源
if (event != null && event.getSource() instanceof Eathquake){
Eathquake earthquake = (Eathquake) event.getSource();
// 当位置赋值,耗时超过5秒,且强度大于6的强度,房子才会塌
if (earthquake.getLoc() > 0 && earthquake.getDuration() > 5 && earthquake.getStrength() > 6){
System.out.println("房子塌:collapse~");
}
} else {
System.out.println("居民做其他的事情");
}
}
}
结果:
-----------------模拟只会狗狗叫---------------
狗狗叫:call~
-----------------模拟狗狗叫,居民跑--------------
狗狗叫:call~
居民跑:run~
-----------------模拟狗狗叫,居民跑,房子塌--------------
狗狗叫:call~
居民跑:run~
房子塌:collapse~