0%

事件驱动编程

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

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

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

1.JAVA回调的例子

1
/**
2
 * @Description java回调
3
 * @Author Anthony
4
 * @Date 2019/6/15
5
 */
6
7
interface Callback {
8
9
    Map<String,String> parse(String html);
10
}
11
12
public class CallbackDemo {
13
14
    // 爬虫工具类
15
    static Map<String,String> send(String URL, Callback callback) {
16
17
        // 模拟爬虫返回的数据
18
        String spiderResponse = "";
19
20
        if ("http://www.baidu.com".equals(URL)) {
21
            spiderResponse = "name=baidu&age=23";
22
23
        }else if("http://www.qq.com".equals(URL)){
24
            spiderResponse = "name=mahuateng&age=24";
25
        }
26
27
        // 回调方法
28
        return callback.parse(spiderResponse);
29
    }
30
31
    public static void main(String[] args) {
32
        String URL = "http://www.baidu.com";
33
        Map<String, String> send = send(URL, gbk -> {
34
35
            Map<String, String> map = new HashMap<>();
36
37
            // 切分&
38
            String[] split = gbk.split("&");
39
40
            // name
41
            map.put(split[0].split("=")[0], split[0].split("=")[1]);
42
43
            // age
44
            map.put(split[1].split("=")[0], split[0].split("=")[1]);
45
46
            return map;
47
        });
48
        System.out.println(send.get("name"));
49
    }
50
}

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

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

1
/**
2
 * @Description JAVA多态
3
 * @Author Anthony
4
 * @Date 2019/6/15
5
 */
6
7
abstract class MyCallback {
8
9
    void method(){
10
        System.out.println("method");
11
    }
12
13
    void method2(){
14
        System.out.println("method2");
15
    }
16
}
17
18
class MyImpl extends MyCallback {
19
20
    @Override
21
    void method() {
22
        System.out.println("Myimpl method");
23
    }
24
}
25
26
public class Demo {
27
28
    public static void main(String[] args) {
29
        MyCallback impl = new MyImpl();
30
        impl.method();
31
        impl.method2();
32
    }
33
}

3.观察者模式的例子

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

1
import java.util.ArrayList;
2
import java.util.List;
3
4
/**
5
 * @Description 观察者模式
6
 * @Author Anthony
7
 * @Date 2019/6/15
8
 */
9
10
/**
11
 * 创建 Observer 类。
12
 */
13
abstract class Observer {
14
    Subject subject;
15
    public abstract void update();
16
}
17
18
/**
19
 * 创建 Subject 类。
20
 */
21
class Subject {
22
23
    // 最重要的地方
24
    private List<Observer> observers = new ArrayList<>();
25
26
    private int state;
27
28
    int getState() {
29
        return state;
30
    }
31
32
    void setState(int state) {
33
        this.state = state;
34
        notifyAllObservers();
35
    }
36
37
    void attach(Observer observer){
38
        observers.add(observer);
39
    }
40
41
    // 最重要的地方
42
    private void notifyAllObservers(){
43
        for (Observer observer : observers) {
44
            observer.update();
45
        }
46
    }
47
}
48
49
/**
50
 * 创建实体观察者类。1
51
 */
52
class BinaryObserver extends Observer{
53
54
    BinaryObserver(Subject subject){
55
        this.subject = subject;
56
        this.subject.attach(this);
57
    }
58
59
    @Override
60
    public void update() {
61
        System.out.println( "BinaryObserver: "+ Integer.toBinaryString( subject.getState() ) );
62
    }
63
}
64
65
/**
66
 * 创建实体观察者类。2
67
 */
68
class OctalObserver extends Observer{
69
70
    OctalObserver(Subject subject){
71
        this.subject = subject;
72
        this.subject.attach(this);
73
    }
74
75
    @Override
76
    public void update() {
77
        System.out.println( "OctalObserver: " + Integer.toOctalString( subject.getState() ) );
78
    }
79
}
80
81
82
83
public class Demo{
84
    public static void main(String[] args) {
85
        Subject subject = new Subject();
86
87
        new OctalObserver(subject);
88
        new BinaryObserver(subject);
89
90
        System.out.println("第一次状态改变: 15");
91
        subject.setState(15);
92
93
        System.out.println("第二次状态改变: 10");
94
        subject.setState(10);
95
    }
96
}

打印结果:

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

事件驱动编程

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

1
/**
2
 * @Description 事件驱动编程
3
 * @Author Anthony
4
 * @Date 2019/6/15
5
 */
6
7
interface ClickCall{
8
    String click(String msg);
9
}
10
11
class MyTask{
12
13
    protected String msg;
14
15
    protected ClickCall clickCall;
16
17
    public MyTask(String msg,ClickCall clickCall) {
18
        this.msg = msg;
19
        this.clickCall = clickCall;
20
    }
21
}
22
23
24
25
public class Demo {
26
27
    // java 栈,也可以当做是队列之类
28
    public static Stack<MyTask> list = new Stack<>();
29
30
    public static void main(String[] args) throws InterruptedException {
31
32
        // 模拟鼠标点击
33
        list.push(new MyTask("右键",msg->{
34
            return "右手点击鼠标"+msg;
35
        }));
36
37
        list.push(new MyTask("左键",msg->{
38
            return "左手点击鼠标"+msg;
39
        }));
40
41
        // 启动一个线程循环List
42
        new Thread(() -> {
43
44
            while (true && !list.empty()) {
45
46
                // pop 方法,从栈顶移除一个,并打印出来
47
                MyTask pop = list.pop();
48
                System.out.println(pop.clickCall.click(pop.msg));
49
            }
50
51
        }).start();
52
53
    }
54
}