看完公司的基于 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
- /**
- * @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();
- }
- }
来源: https://www.cnblogs.com/yal950727/p/11028482.html