简要说明
事件处理模型
场景示例:小朋友睡醒了哭,饿!
一、v1版本(披着面向对象的外衣的面向过程)
/*** @description: 观察者模式-v1版本(披着面向对象的外衣的面向过程)* @author: flygo* @time: 2022/7/18 16:57*/
public class ObserverMain {public static void main(String[] args) {boolean cry = false;if (!cry) {// 进行处理}}
}
二、v2版本(面向对象的傻等)
/*** @description: 观察者模式-v2版本(面向对象的傻等)* @author: flygo* @time: 2022/7/18 16:57*/
public class ObserverMain {public static void main(String[] args) {Child child = new Child();while (!child.isCry()) {try {Thread.sleep(10000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Observing......");}}
}class Child {private boolean cry = false;public boolean isCry() {return cry;}public void setCry(boolean cry) {this.cry = cry;}public void wakeUp() {System.out.println("Waked Up!Crying.......");}
}
三、v3版本(加入观察者)
/*** @description: 观察者模式-v3版本(加入观察者)* @author: flygo* @time: 2022/7/18 16:57*/
public class ObserverMain {public static void main(String[] args) {Child child = new Child();child.wakeUp();}
}class Dad {public void feed() {System.out.println("Dad feeding...");}
}class Child {private boolean cry = false;private Dad dad = new Dad();public boolean isCry() {return cry;}public void setCry(boolean cry) {this.cry = cry;}public void wakeUp() {cry = true;dad.feed();}
}
四、v4版本(加入多个观察者)
/*** @description: 观察者模式-v4版本(加入多个观察者)* @author: flygo* @time: 2022/7/18 16:57*/
public class ObserverMain {public static void main(String[] args) {Child child = new Child();child.wakeUp();}
}class Dad {public void feed() {System.out.println("Dad feeding...");}
}class Mum {public void hug() {System.out.println("Mum hugging...");}
}class Dog {public void wang() {System.out.println("dog wang...");}
}class Child {private boolean cry = false;private Dad dad = new Dad();private Mum mum = new Mum();private Dog dog = new Dog();public boolean isCry() {return cry;}public void setCry(boolean cry) {this.cry = cry;}public void wakeUp() {cry = true;dad.feed();mum.hug();dog.wang();}
}
五、v5版本(加入多个观察者,采用接口的实现方式)
/*** @description: 观察者模式-v5版本(加入多个观察者,采用接口实现的方式)* @author: flygo* @time: 2022/7/18 16:57*/
public class ObserverMain {public static void main(String[] args) {Child child = new Child();child.wakeUp();}
}interface Observer {void actionOnWakeUp();
}class Dad implements Observer {public void feed() {System.out.println("Dad feeding...");}@Overridepublic void actionOnWakeUp() {feed();}
}class Mum implements Observer {public void hug() {System.out.println("Mum hugging...");}@Overridepublic void actionOnWakeUp() {hug();}
}class Dog implements Observer {public void wang() {System.out.println("dog wang...");}@Overridepublic void actionOnWakeUp() {wang();}
}class Child {private boolean cry = false;private List<Observer> observerList = new ArrayList<>();{observerList.add(new Dad());observerList.add(new Mum());observerList.add(new Dog());}public boolean isCry() {return cry;}public void setCry(boolean cry) {this.cry = cry;}public void wakeUp() {cry = true;for (Observer o : observerList) {o.actionOnWakeUp();}}
}
六、v6版本(加入多个观察者,增加事件对象)
import java.util.ArrayList;
import java.util.List;/*** @description: 观察者模式-v5版本(加入多个观察者,增加事件对象)* @author: flygo* @time: 2022/7/18 16:57*/
public class ObserverMain {public static void main(String[] args) {Child child = new Child();child.wakeUp();}
}class WakeUpEvent {long timestamp;String loc;public WakeUpEvent(long timestamp, String loc) {this.timestamp = timestamp;this.loc = loc;}
}interface Observer {void actionOnWakeUp(WakeUpEvent event);
}class Dad implements Observer {public void feed() {System.out.println("Dad feeding...");}@Overridepublic void actionOnWakeUp(WakeUpEvent event) {feed();}
}class Mum implements Observer {public void hug() {System.out.println("Mum hugging...");}@Overridepublic void actionOnWakeUp(WakeUpEvent event) {hug();}
}class Dog implements Observer {public void wang() {System.out.println("dog wang...");}@Overridepublic void actionOnWakeUp(WakeUpEvent event) {wang();}
}class Child {private boolean cry = false;private List<Observer> observerList = new ArrayList<>();{observerList.add(new Dad());observerList.add(new Mum());observerList.add(new Dog());}public boolean isCry() {return cry;}public void setCry(boolean cry) {this.cry = cry;}public void wakeUp() {cry = true;WakeUpEvent event = new WakeUpEvent(System.currentTimeMillis(), "bed");for (Observer o : observerList) {o.actionOnWakeUp(event);}}
}
七、v7版本(加入多个观察者,增加事件对象且时间对象增加事件源)
import java.util.ArrayList;
import java.util.List;/*** @description: 观察者模式-v5版本(加入多个观察者,增加事件对象且事件对象增加事件源)* @author: flygo* @time: 2022/7/18 16:57*/
public class ObserverMain {public static void main(String[] args) {Child child = new Child();child.wakeUp();}
}interface Observer {void actionOnWakeUp(WakeUpEvent event);
}class Dad implements Observer {public void feed() {System.out.println("Dad feeding...");}@Overridepublic void actionOnWakeUp(WakeUpEvent event) {feed();}
}class Mum implements Observer {public void hug() {System.out.println("Mum hugging...");}@Overridepublic void actionOnWakeUp(WakeUpEvent event) {hug();}
}class Dog implements Observer {public void wang() {System.out.println("dog wang...");}@Overridepublic void actionOnWakeUp(WakeUpEvent event) {wang();}
}class WakeUpEvent {long timestamp;String loc;Child child;public WakeUpEvent(long timestamp, String loc, Child child) {this.timestamp = timestamp;this.loc = loc;this.child = child;}
}class Child {private boolean cry = false;private List<Observer> observerList = new ArrayList<>();{observerList.add(new Dad());observerList.add(new Mum());observerList.add(new Dog());}public boolean isCry() {return cry;}public void setCry(boolean cry) {this.cry = cry;}public void wakeUp() {cry = true;WakeUpEvent event = new WakeUpEvent(System.currentTimeMillis(), "bed", this);for (Observer o : observerList) {o.actionOnWakeUp(event);}}
}
八、v8版本(加入多个观察者,事件体系)
import java.util.ArrayList;
import java.util.List;/*** @description: 观察者模式-v5版本(加入多个观察者,事件体系)* @author: flygo* @time: 2022/7/18 16:57*/
public class ObserverMain {public static void main(String[] args) {Child child = new Child();child.wakeUp();}
}interface Observer {void actionOnWakeUp(WakeUpEvent event);
}class Dad implements Observer {public void feed() {System.out.println("Dad feeding...");}@Overridepublic void actionOnWakeUp(WakeUpEvent event) {feed();}
}class Mum implements Observer {public void hug() {System.out.println("Mum hugging...");}@Overridepublic void actionOnWakeUp(WakeUpEvent event) {hug();}
}class Dog implements Observer {public void wang() {System.out.println("dog wang...");}@Overridepublic void actionOnWakeUp(WakeUpEvent event) {wang();}
}abstract class Event<T> {// 事件源abstract T getSource();
}class WakeUpEvent extends Event<Child> {long timestamp;String loc;Child source;public WakeUpEvent(long timestamp, String loc, Child source) {this.timestamp = timestamp;this.loc = loc;this.source = source;}@OverrideChild getSource() {return source;}
}class Child {private boolean cry = false;private List<Observer> observerList = new ArrayList<>();{observerList.add(new Dad());observerList.add(new Mum());observerList.add(new Dog());}public boolean isCry() {return cry;}public void setCry(boolean cry) {this.cry = cry;}public void wakeUp() {cry = true;WakeUpEvent event = new WakeUpEvent(System.currentTimeMillis(), "bed", this);for (Observer o : observerList) {o.actionOnWakeUp(event);}}
}
九、v9版本(java原生awt button使用的观察模式和模拟原生awt Button实现观察者模式)
1、java原生awt button使用的观察模式
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;/*** @description: 简单的一个按钮点击小例子演示java原生使用的观察者模式* @author: flygo* @time: 2022/7/19 10:20*/
public class TestFrame extends Frame {public void launch() {Button button = new Button("press me");button.addActionListener(new MyButtonActionListener());button.addActionListener(new MyButtonActionListener2());this.add(button);this.pack();this.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {super.windowClosing(e);System.exit(0);}});this.setLocation(400, 400);this.setVisible(true);}public static void main(String[] args) {new TestFrame().launch();}
}class MyButtonActionListener implements ActionListener {@Overridepublic void actionPerformed(ActionEvent e) {((Button) e.getSource()).setLabel("press me again!");System.out.println("button pressed!");}
}class MyButtonActionListener2 implements ActionListener {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("button pressed again!");}
}
2、模拟原生awt Button实现观察者模式
核心思路和逻辑
- 定义事件类
ActionEvent
- 定义接口类
ActionListener
和接口方法void actionPerformed(ActionEvent e);
- 自定义
Button
类,模拟按钮点击事件
- 自定义监听者
MyActionEventListener
和MyActionEventListener2
实现接口void actionPerformed(ActionEvent e);
- main主方法程序
Button
添加监听者MyActionEventListener
和MyActionEventListener2
, 模拟Button
调用点击方法buttonPressed
import java.util.ArrayList;
import java.util.List;/*** @description: 模拟Java原生awt button观察者模式* @author: flygo* @time: 2022/7/19 11:09*/
public class ButtonObserverMain {public static void main(String[] args) {Button button = new Button();button.addActionListener(new MyActionEventListener());button.addActionListener(new MyActionEventListener2());button.buttonPressed();}
}interface ActionListener {void actionPerformed(ActionEvent e);
}class ActionEvent {long when;Object source;public ActionEvent(long when, Object source) {this.when = when;this.source = source;}public long getWhen() {return when;}public Object getSource() {return source;}
}class Button {private List<ActionListener> listenerList = new ArrayList<>();public void buttonPressed() {ActionEvent event = new ActionEvent(System.currentTimeMillis(), this);for (ActionListener listener : listenerList) {listener.actionPerformed(event);}}public void addActionListener(ActionListener listener) {this.listenerList.add(listener);}
}class MyActionEventListener implements ActionListener {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("button pressed!");}
}class MyActionEventListener2 implements ActionListener {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("button pressed again!");}
}
十、v10版本(使用Lambda表达式实现回调或钩子函数)
JavaScript 中有钩子函数,其实就是观察者模式
import java.util.ArrayList;
import java.util.List;/*** @description: 模拟Java原生awt button观察者模式-钩子函数(hook)、回调(callback)、observer* @author: flygo* @time: 2022/7/19 11:09*/
public class ButtonObserverMain {public static void main(String[] args) {Button button = new Button();button.addActionListener(new MyActionEventListener());button.addActionListener(new MyActionEventListener2());button.addActionListener((e) -> {System.out.println("This is lambda listener!");});button.buttonPressed();}
}interface ActionListener {void actionPerformed(ActionEvent e);
}class ActionEvent {long when;Object source;public ActionEvent(long when, Object source) {this.when = when;this.source = source;}public long getWhen() {return when;}public Object getSource() {return source;}
}class Button {private List<ActionListener> listenerList = new ArrayList<>();public void buttonPressed() {ActionEvent event = new ActionEvent(System.currentTimeMillis(), this);for (ActionListener listener : listenerList) {listener.actionPerformed(event);}}public void addActionListener(ActionListener listener) {this.listenerList.add(listener);}
}class MyActionEventListener implements ActionListener {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("button pressed!");}
}class MyActionEventListener2 implements ActionListener {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("button pressed again!");}
}
十一、JavaScript中的event事件
在很多系统中,Observer模式往往和责任链共同负责对于事件的处理,其中的某一个observer负责是否将事件往下传
<script type="text/javascript">function handle() {alert(event.target.value);}
</script><input type="button" value="press me" name="button" onclick="handle()" />
十二、源码地址
https://github.com/jxaufang168/Design-Patternshttps://github.com/jxaufang168/Design-Patterns