事件驅動程式設計
阿新 • • 發佈:2019-06-15
看完公司的基於Netty的遊戲框架,框架中用到了多型,函數語言程式設計和事件驅動程式設計,第一次看到事件驅動的時候,就想到跟觀察者模式很像.
事件驅動初上手感覺還很好用,在我自己寫的專案裡,要寫很多爬蟲,比如下面爬蟲的例子,我只是想關心拼接URL地址,和關心不同的網站怎麼解析DOM元素,寫一個回撥就好
多型,函數語言程式設計和事件驅動程式設計,這三個還是然讓我學到很多,可以用一個框架的基礎,比如在Netty中,繼承SimpleChannelInboundHandler<TextWebSocketFrame>
,實現這裡裡面的方法,就能接收到請求,很方便.
1.JAVA回撥的例子
/** * @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.觀察者模式中的多型的例子
/** * @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.觀察者模式的例子
參考的是菜鳥教程中設計模式的例子
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);
}
}
列印結果:
第一次狀態改變: 15
OctalObserver: 17
BinaryObserver: 1111
第二次狀態改變: 10
OctalObserver: 12
BinaryObserver: 1010
事件驅動程式設計
雖然看了事件驅動的定義,雖然知道是什麼意思,但是不知道該怎麼說出來,大概就是,寫個while迴圈遍歷佇列,或者集合的中資料
/**
* @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();
}
}
參考
我的部落格:http://yanganlin.com