Netty -Event Driven Model(如何理解Netty中的事件驱动模型)
如何理解Netty中的事件驱动模型
在现代软件开发中,事件驱动模型是处理用户交互、异步操作和复杂系统交互的关键技术。本文将深入探讨事件驱动模型的核心组件、事件驱动的步骤、事件与驱动的关系,并以Java语言为例,展示如何在实际编程中应用这一模型。
事件驱动模型的核心组件
事件驱动模型依赖于几个核心组件,它们共同作用以响应和处理事件。以下是这些组件的简要描述:
- 事件源(Event Source) : 事件源是产生事件的对象
- 事件对象(Event Object):事件对象是事件本身,封装了事件信息的实体
- 事件监听器(Event Listener):事件监听器是用于监听特定事件的对象,用作通知分发等等
- 事件处理器(Event Handler):用于处理事件
事件驱动的步骤
实现事件驱动模型通常遵循以下步骤:
- 首先,你需要定义一个事件源,事件,监听器,处理器
- 其次,创建监听器,在监听器中将事件和处理器绑定
- 具体实现处理器
事件和驱动的关系
- 事件和驱动之间的流转关系可以是同步/非同步,阻塞/非阻塞的
- 事件和驱动之间的映射关系可以是1对1,1对多,多对多
- 事件、监听器、驱动之间的关系,可以由事件和监听器流转关系 同步/非同步,阻塞/非阻塞 ➕监听器和驱动流转关系 同步/非同步,阻塞/非阻塞
- 事件、监听器、驱动的映射关系事件和监听器映射关系 1对1,1对多,多对多,监听器和驱动的映射关系1对1,1对多,多对多
由此将会产生*同步阻塞的1对1事件驱动,同步阻塞的1对多事件驱动,同步阻塞的多对多事件驱动,同步非阻塞的1对1事件驱动,同步非阻塞的1对多事件驱动,同步非阻塞的多对多事件驱动* 等等2✖️2✖️3=12 种模式
常用事件驱动模式示例
同步阻塞的1对1的事件驱动-命令模式
@startuml
interface Command {
+execute()
}
class Light {
+turnOn() : void
+turnOff() : void
}
class LightOnCommand {
-light : Light
+LightOnCommand(light : Light)
+execute() : void
}
class LightOffCommand {
-light : Light
+LightOffCommand(light : Light)
+execute() : void
}
class RemoteControl {
-command : Command
+setCommand(command : Command) : void
+pressButton() : void
}
LightOnCommand o-- Light :lightOn
LightOffCommand o-- Light : lightOff
RemoteControl o-- Command : uses
Command -->LightOnCommand
Command -->LightOffCommand
@enduml
public interface Command {
void execute();
}
public class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOn();
}
}
public class LightOffCommand implements Command {
private Light light;
public LightOffCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOff();
}
}
public class Light {
public void turnOn() {
System.out.println("Light is on");
}
public void turnOff() {
System.out.println("Light is off");
}
}
public class RemoteControl {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void pressButton() {
command.execute();
}
}
public class Client {
public static void main(String[] args) {
Light light = new Light();
Command lightOn = new LightOnCommand(light);
Command lightOff = new LightOffCommand(light);
RemoteControl remote = new RemoteControl();
// Switching on the light
remote.setCommand(lightOn);
remote.pressButton();
// Switching off the light
remote.setCommand(lightOff);
remote.pressButton();
}
}
@startuml
interface Command {
+execute()
}
class Light {
+turnOn() : void
+turnOff() : void
}
class LightOnCommand {
-light : Light
+LightOnCommand(light : Light)
+execute() : void
}
class LightOffCommand {
-light : Light
+LightOffCommand(light : Light)
+execute() : void
}
class RemoteControl {
-command : Command
+setCommand(command : Command) : void
+pressButton() : void
}
LightOnCommand o-- Light :lightOn
LightOffCommand o-- Light : lightOff
RemoteControl o-- Command : uses
Command -->LightOnCommand
Command -->LightOffCommand
@enduml
public interface Command {
void execute();
}
public class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOn();
}
}
public class LightOffCommand implements Command {
private Light light;
public LightOffCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOff();
}
}
public class Light {
public void turnOn() {
System.out.println("Light is on");
}
public void turnOff() {
System.out.println("Light is off");
}
}
public class RemoteControl {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void pressButton() {
command.execute();
}
}
public class Client {
public static void main(String[] args) {
Light light = new Light();
Command lightOn = new LightOnCommand(light);
Command lightOff = new LightOffCommand(light);
RemoteControl remote = new RemoteControl();
// Switching on the light
remote.setCommand(lightOn);
remote.pressButton();
// Switching off the light
remote.setCommand(lightOff);
remote.pressButton();
}
}
同步阻塞的1对多的事件驱动-观察者模式
@startuml
interface Observer {
+update(message : String) : void
}
interface Subject {
+registerObserver(o : Observer) : void
+removeObserver(o : Observer) : void
+notifyObservers() : void
}
class MessageBoard {
-observers : List<Observer>
-message : String
+MessageBoard()
+setMessage(message : String) : void
+registerObserver(o : Observer) : void
+removeObserver(o : Observer) : void
+notifyObservers() : void
}
class User {
-name : String
+User(name : String)
+update(message : String) : void
}
class Client {
+run() : void
}
Observer <|-- User
Subject <|-- MessageBoard
MessageBoard "1" o-- "many" Observer : notifies
Client --> MessageBoard :regist/setMessage/notify
@enduml
import java.util.ArrayList;
import java.util.List;
public interface Observer {
void update(String message);
}
public interface Subject {
void registerObserver(Observer o);
void removeObserver(Observer o);
void notifyObservers();
}
public class MessageBoard implements Subject {
private List<Observer> observers;
private String message;
public MessageBoard() {
observers = new ArrayList<>();
}
public void setMessage(String message) {
this.message = message;
notifyObservers();
}
@Override
public void registerObserver(Observer o) {
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
int i = observers.indexOf(o);
if (i >= 0) {
observers.remove(i);
}
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(message);
}
}
}
public class User implements Observer {
private String name;
public User(String name) {
this.name = name;
}
@Override
public void update(String message) {
System.out.println(name + " received message: " + message);
}
}
public class ObserverPatternDemo {
public static void main(String[] args) {
MessageBoard messageBoard = new MessageBoard();
User alice = new User("Alice");
User bob = new User("Bob");
messageBoard.registerObserver(alice);
messageBoard.registerObserver(bob);
messageBoard.setMessage("Hello Observer Pattern!");
messageBoard.removeObserver(bob);
messageBoard.setMessage("Updated message after removing Bob.");
}
}
@startuml
interface Observer {
+update(message : String) : void
}
interface Subject {
+registerObserver(o : Observer) : void
+removeObserver(o : Observer) : void
+notifyObservers() : void
}
class MessageBoard {
-observers : List<Observer>
-message : String
+MessageBoard()
+setMessage(message : String) : void
+registerObserver(o : Observer) : void
+removeObserver(o : Observer) : void
+notifyObservers() : void
}
class User {
-name : String
+User(name : String)
+update(message : String) : void
}
class Client {
+run() : void
}
Observer <|-- User
Subject <|-- MessageBoard
MessageBoard "1" o-- "many" Observer : notifies
Client --> MessageBoard :regist/setMessage/notify
@enduml
import java.util.ArrayList;
import java.util.List;
public interface Observer {
void update(String message);
}
public interface Subject {
void registerObserver(Observer o);
void removeObserver(Observer o);
void notifyObservers();
}
public class MessageBoard implements Subject {
private List<Observer> observers;
private String message;
public MessageBoard() {
observers = new ArrayList<>();
}
public void setMessage(String message) {
this.message = message;
notifyObservers();
}
@Override
public void registerObserver(Observer o) {
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
int i = observers.indexOf(o);
if (i >= 0) {
observers.remove(i);
}
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(message);
}
}
}
public class User implements Observer {
private String name;
public User(String name) {
this.name = name;
}
@Override
public void update(String message) {
System.out.println(name + " received message: " + message);
}
}
public class ObserverPatternDemo {
public static void main(String[] args) {
MessageBoard messageBoard = new MessageBoard();
User alice = new User("Alice");
User bob = new User("Bob");
messageBoard.registerObserver(alice);
messageBoard.registerObserver(bob);
messageBoard.setMessage("Hello Observer Pattern!");
messageBoard.removeObserver(bob);
messageBoard.setMessage("Updated message after removing Bob.");
}
}
同步阻塞的多对多的事件驱动-事件分发模式
// 事件类型,可以根据需要扩展
public interface Event {
String getEventType();
}
// 定义事件监听器接口
public interface EventListener {
void onEvent(Event event);
}
//Dispatcher类,用于注册监听器和分发事件
import java.util.HashMap;
import java.util.Map;
public class EventDispatcher {
private Map<String, EventListener> listeners = new HashMap<>();
public void registerListener(String eventType, EventListener listener) {
listeners.put(eventType, listener);
}
public void dispatchEvent(Event event) {
EventListener listener = listeners.get(event.getEventType());
if (listener != null) {
listener.onEvent(event);
} else {
System.out.println("No listener for event: " + event.getEventType());
}
}
}
// 创建具体的事件类
public class ConcreteEvent implements Event {
private String eventType;
private Object data;
public ConcreteEvent(String eventType, Object data) {
this.eventType = eventType;
this.data = data;
}
@Override
public String getEventType() {
return eventType;
}
public Object getData() {
return data;
}
}
//创建具体的事件监听器
public class ConcreteEventListener implements EventListener {
private String listenerType;
public ConcreteEventListener(String type) {
this.listenerType = type;
}
@Override
public void onEvent(Event event) {
if (event.getEventType().equals(listenerType)) {
// 处理事件
System.out.println("Handling event: " + event.getEventType());
// 可以访问事件的数据
System.out.println("Event data: " + ((ConcreteEvent) event).getData());
}
}
}
//演示整个Dispatcher模式的运作
public class DispatcherDemo {
public static void main(String[] args) {
EventDispatcher dispatcher = new EventDispatcher();
// 创建事件
Event event1 = new ConcreteEvent("TYPE1", "Data for TYPE1");
Event event2 = new ConcreteEvent("TYPE2", "Data for TYPE2");
// 创建监听器
EventListener listener1 = new ConcreteEventListener("TYPE1");
EventListener listener2 = new ConcreteEventListener("TYPE2");
// 注册监听器
dispatcher.registerListener("TYPE1", listener1);
dispatcher.registerListener("TYPE2", listener2);
// 分发事件
dispatcher.dispatchEvent(event1);
dispatcher.dispatchEvent(event2);
}
}
// 事件类型,可以根据需要扩展
public interface Event {
String getEventType();
}
// 定义事件监听器接口
public interface EventListener {
void onEvent(Event event);
}
//Dispatcher类,用于注册监听器和分发事件
import java.util.HashMap;
import java.util.Map;
public class EventDispatcher {
private Map<String, EventListener> listeners = new HashMap<>();
public void registerListener(String eventType, EventListener listener) {
listeners.put(eventType, listener);
}
public void dispatchEvent(Event event) {
EventListener listener = listeners.get(event.getEventType());
if (listener != null) {
listener.onEvent(event);
} else {
System.out.println("No listener for event: " + event.getEventType());
}
}
}
// 创建具体的事件类
public class ConcreteEvent implements Event {
private String eventType;
private Object data;
public ConcreteEvent(String eventType, Object data) {
this.eventType = eventType;
this.data = data;
}
@Override
public String getEventType() {
return eventType;
}
public Object getData() {
return data;
}
}
//创建具体的事件监听器
public class ConcreteEventListener implements EventListener {
private String listenerType;
public ConcreteEventListener(String type) {
this.listenerType = type;
}
@Override
public void onEvent(Event event) {
if (event.getEventType().equals(listenerType)) {
// 处理事件
System.out.println("Handling event: " + event.getEventType());
// 可以访问事件的数据
System.out.println("Event data: " + ((ConcreteEvent) event).getData());
}
}
}
//演示整个Dispatcher模式的运作
public class DispatcherDemo {
public static void main(String[] args) {
EventDispatcher dispatcher = new EventDispatcher();
// 创建事件
Event event1 = new ConcreteEvent("TYPE1", "Data for TYPE1");
Event event2 = new ConcreteEvent("TYPE2", "Data for TYPE2");
// 创建监听器
EventListener listener1 = new ConcreteEventListener("TYPE1");
EventListener listener2 = new ConcreteEventListener("TYPE2");
// 注册监听器
dispatcher.registerListener("TYPE1", listener1);
dispatcher.registerListener("TYPE2", listener2);
// 分发事件
dispatcher.dispatchEvent(event1);
dispatcher.dispatchEvent(event2);
}
}
同步非阻塞的1对多的事件驱动模式-Reactor
该模式已经被同行吹的起飞了,就不详细说明了 示例: 略
其他排列组合的事件驱动模式
可能设计的还不够健壮,可能还没有应用到非常有名的软件中,但他是存在的,请勿忘记!!!
可能设计的还不够健壮,可能还没有应用到非常有名的软件中,但他是存在的,请勿忘记!!!
5. 结论
事件驱动模型是现代软件开发中不可或缺的一部分,它允许程序以各种不同的方式响应用户操作和其他事件。通过理解事件驱动模型的核心组件和实现步骤及关系,开发者可以更有效地构建响应式和高效的应用程序,可以更加高屋建瓴的理解市面上的一些所谓的高大上的知识点