看完公司的基於Netty的遊戲框架,框架中用到了多態,函數式編程和事件驅動編程,第一次看到事件驅動的時候,就想到跟觀察者模式很像.html
事件驅動初上手感受還很好用,在我本身寫的項目裏,要寫不少爬蟲,好比下面爬蟲的例子,我只是想關心拼接URL地址,和關心不一樣的網站怎麼解析DOM元素,寫一個回調就好java
多態,函數式編程和事件驅動編程,這三個仍是然讓我學到不少,能夠用一個框架的基礎,好比在Netty中,繼承SimpleChannelInboundHandler<TextWebSocketFrame>
,實現這裏裏面的方法,就能接收到請求,很方便.shell
/** * @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,和怎麼分析爬蟲返回的數據編程
/** * @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(); } }
參考的是菜鳥教程中設計模式的例子設計模式
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循環遍歷隊列,或者集合的中數據ide
/** * @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函數式編程