事件驱动编程

看完公司的基于Netty的游戏框架,框架中用到了多态,函数式编程和事件驱动编程,第一次看到事件驱动的时候,就想到跟观察者模式很像.

事件驱动初上手感觉还很好用,在我自己写的项目里,要写很多爬虫,比如下面爬虫的例子,我只是想关心拼接URL地址,和关心不同的网站怎么解析DOM元素,写一个回调就好

多态,函数式编程和事件驱动编程,这三个还是然让我学到很多,可以用一个框架的基础,比如在Netty中,继承SimpleChannelInboundHandler<TextWebSocketFrame>,实现这里里面的方法,就能接收到请求,很方便.


1.JAVA回调的例子

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
/**
* @Description java回调
* @Author Anthony
* @Date 2019/6/15
*/

interface Callback {

Map<String,String> parse(String html);
}

public class CallbackDemo {

// 爬虫工具类
static Map<String,String> send(String URL, Callback callback) {

// 模拟爬虫返回的数据
String spiderResponse = "";

if ("http://www.baidu.com".equals(URL)) {
spiderResponse = "name=baidu&age=23";

}else if("http://www.qq.com".equals(URL)){
spiderResponse = "name=mahuateng&age=24";
}

// 回调方法
return callback.parse(spiderResponse);
}

public static void main(String[] args) {
String URL = "http://www.baidu.com";
Map<String, String> send = send(URL, gbk -> {

Map<String, String> map = new HashMap<>();

// 切分&
String[] split = gbk.split("&");

// name
map.put(split[0].split("=")[0], split[0].split("=")[1]);

// age
map.put(split[1].split("=")[0], split[0].split("=")[1]);

return map;
});
System.out.println(send.get("name"));
}
}

这样写各种简单的java爬虫的时候,只需要关心URL,和怎么分析爬虫返回的数据

2.观察者模式中的多态的例子

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
/**
* @Description JAVA多态
* @Author Anthony
* @Date 2019/6/15
*/

abstract class MyCallback {

void method(){
System.out.println("method");
}

void method2(){
System.out.println("method2");
}
}

class MyImpl extends MyCallback {

@Override
void method() {
System.out.println("Myimpl method");
}
}

public class Demo {

public static void main(String[] args) {
MyCallback impl = new MyImpl();
impl.method();
impl.method2();
}
}

3.观察者模式的例子

参考的是菜鸟教程中设计模式的例子

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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import java.util.ArrayList;
import java.util.List;

/**
* @Description 观察者模式
* @Author Anthony
* @Date 2019/6/15
*/

/**
* 创建 Observer 类。
*/
abstract class Observer {
Subject subject;
public abstract void update();
}

/**
* 创建 Subject 类。
*/
class Subject {

// 最重要的地方
private List<Observer> observers = new ArrayList<>();

private int state;

int getState() {
return state;
}

void setState(int state) {
this.state = state;
notifyAllObservers();
}

void attach(Observer observer){
observers.add(observer);
}

// 最重要的地方
private void notifyAllObservers(){
for (Observer observer : observers) {
observer.update();
}
}
}

/**
* 创建实体观察者类。1
*/
class BinaryObserver extends Observer{

BinaryObserver(Subject subject){
this.subject = subject;
this.subject.attach(this);
}

@Override
public void update() {
System.out.println( "BinaryObserver: "+ Integer.toBinaryString( subject.getState() ) );
}
}

/**
* 创建实体观察者类。2
*/
class OctalObserver extends Observer{

OctalObserver(Subject subject){
this.subject = subject;
this.subject.attach(this);
}

@Override
public void update() {
System.out.println( "OctalObserver: " + Integer.toOctalString( subject.getState() ) );
}
}



public class Demo{
public static void main(String[] args) {
Subject subject = new Subject();

new OctalObserver(subject);
new BinaryObserver(subject);

System.out.println("第一次状态改变: 15");
subject.setState(15);

System.out.println("第二次状态改变: 10");
subject.setState(10);
}
}

打印结果:

1
2
3
4
5
6
第一次状态改变: 15
OctalObserver: 17
BinaryObserver: 1111
第二次状态改变: 10
OctalObserver: 12
BinaryObserver: 1010

事件驱动编程

虽然看了事件驱动的定义,虽然知道是什么意思,但是不知道该怎么说出来,大概就是,写个while循环遍历队列,或者集合的中数据

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
52
53
54
/**
* @Description 事件驱动编程
* @Author Anthony
* @Date 2019/6/15
*/

interface ClickCall{
String click(String msg);
}

class MyTask{

protected String msg;

protected ClickCall clickCall;

public MyTask(String msg,ClickCall clickCall) {
this.msg = msg;
this.clickCall = clickCall;
}
}



public class Demo {

// java 栈,也可以当做是队列之类
public static Stack<MyTask> list = new Stack<>();

public static void main(String[] args) throws InterruptedException {

// 模拟鼠标点击
list.push(new MyTask("右键",msg->{
return "右手点击鼠标"+msg;
}));

list.push(new MyTask("左键",msg->{
return "左手点击鼠标"+msg;
}));

// 启动一个线程循环List
new Thread(() -> {

while (true && !list.empty()) {

// pop 方法,从栈顶移除一个,并打印出来
MyTask pop = list.pop();
System.out.println(pop.clickCall.click(pop.msg));
}

}).start();

}
}