自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Java進階:用匿名內(nèi)部類實現(xiàn) Java 同步回調(diào)

開發(fā) 后端
在一個應用系統(tǒng)中,不論使用何種編程語言,模塊之間要進行調(diào)用,僅存在三種方式:同步調(diào)用、異步調(diào)用、回調(diào)。本文就其中回調(diào)方式進行詳細解讀,并通過匿名內(nèi)部類的手段,在最后實現(xiàn)一個同步回調(diào)的過程。

在一個應用系統(tǒng)中,不論使用何種編程語言,模塊之間要進行調(diào)用,僅存在三種方式:同步調(diào)用、異步調(diào)用、回調(diào)。本文就其中回調(diào)方式進行詳細解讀,并通過匿名內(nèi)部類的手段,在最后實現(xiàn)一個同步回調(diào)的過程。

[[349149]]

一、回調(diào)的意義

在學習回調(diào)之前,我們需要知道使用回調(diào)的原因,和回調(diào)的應用場景。

不如先思考兩個問題:

  • 棧底對棧頂通常是不可見的,但是棧頂有時需要直接調(diào)用棧底
  • 上級派下級做事,在此期間,下級可能需要通過上級獲取高權限的協(xié)助

而在本例中,回調(diào)方式被用來處理爬取后的大量返回數(shù)據(jù)。在業(yè)務層面,這些數(shù)據(jù)被安排在調(diào)用方進行處理,但是調(diào)用方卻沒有處理這些數(shù)據(jù)的足夠權限。于是,通過回調(diào),業(yè)務被很好的分層并且執(zhí)行。

二、如何實現(xiàn)同步回調(diào)

本文對同步回調(diào)的業(yè)務需求如下:

  • 回調(diào)方調(diào)用調(diào)用方進行數(shù)據(jù)爬取
  • 調(diào)用方調(diào)用回調(diào)方進行數(shù)據(jù)存儲
  • 調(diào)用方調(diào)用回調(diào)方進行日志記錄

根據(jù)需求可以得到回調(diào)過程的時序圖:

相應代碼如下:

  1. public interface Handler { 
  2.     void handle(String info); 
  3.  
  4. public class Task { 
  5.     private String info; 
  6.  
  7.     private void setInfo(String info) { 
  8.         this.info = info; 
  9.     } 
  10.  
  11.     public void call() { 
  12.         Crawler.getInstance().crawl(new Handler() { 
  13.             @Override 
  14.             public void handle(String info) { 
  15.                 setInfo(info); 
  16.             } 
  17.         }); 
  18.     } 
  19.  
  20. public class Crawler { 
  21.     private static Crawler instance = null
  22.  
  23.     public static Crawler getInstance() { 
  24.         if (instance == null) { 
  25.             instance = new Crawler(); 
  26.         } 
  27.         return instance; 
  28.     } 
  29.  
  30.     private String getInfo() { 
  31.         return "the info from crawler"; 
  32.     } 
  33.  
  34.     public void crawl(Handler handler) { 
  35.         handler.handle(getInfo()); 
  36.     } 

三、遇到的問題

如果我們使用代碼來實現(xiàn)上述回調(diào)過程,不難會發(fā)現(xiàn)這樣一個問題:Task調(diào)用Crawler,Crawler調(diào)用Handler,Hanlder調(diào)用Task。很明顯,此處存在一個環(huán),產(chǎn)生了循環(huán)依賴的問題,而接口可以為我們提供良好的解決方案。

四、為什么通過匿名內(nèi)部類的方式

用 Java 實現(xiàn)同步回調(diào)有許多方式,為什么我們要通過匿名內(nèi)部類的方式來實現(xiàn)回調(diào),直接回調(diào)不香嗎?

不妨先看看直接回調(diào)的順序圖:

相應代碼如下:

  1. public interface Handler { 
  2.     void handle(String info); 
  3.  
  4. public class Task implements Handler{ 
  5.     private String info; 
  6.  
  7.     private void setInfo(String info) { 
  8.         this.info = info; 
  9.     } 
  10.  
  11.     public void call() { 
  12.         Crawler.getInstance().crawl(this); 
  13.     } 
  14.  
  15.     @Override 
  16.     public void handle(String info) { 
  17.         setInfo(info); 
  18.     } 
  19.  
  20. public class Crawler { 
  21.     private static Crawler instance = null
  22.  
  23.     public static Crawler getInstance() { 
  24.         if (instance == null) { 
  25.             instance = new Crawler(); 
  26.         } 
  27.         return instance; 
  28.     } 
  29.  
  30.     private String getInfo() { 
  31.         return "the info from crawler"; 
  32.     } 
  33.  
  34.     public void crawl(Handler handler) { 
  35.         handler.handle(getInfo()); 
  36.     } 

直接回調(diào)帶來的最大問題便是回調(diào)接口的暴露,也就是說回調(diào)接口不一定用于回調(diào),也可以用于直接訪問。這在業(yè)務層面的設計上是絕對不允許的,而匿名內(nèi)部類在執(zhí)行回調(diào)等特定業(yè)務的同時,可以很好的對外隱藏用于回調(diào)的接口。

五、總結(jié)

  • 常規(guī)類不保證接口安全性:常規(guī)接口通常可以設定權限,但不可以指定訪問類,也就是說要么都可以訪問,要么都拒絕訪問。而內(nèi)部類中接口可以指定訪問類。
  • 內(nèi)部類保證接口安全性:內(nèi)部類接口通常是對外隱藏的,那么如何使得內(nèi)部類對指定訪問類暴露呢?方法很簡單,只需要通過外部類實例化內(nèi)部類,并對指定類傳參,便可以使得指定類對內(nèi)部類可訪問。
  • 內(nèi)部類的安全性加上其對外部類的完全權限,這使得其成為實現(xiàn)回調(diào)的首選方案。在JAVA8中,lambda表達式本質(zhì)上就是匿名內(nèi)部類的語法糖。

注:匿名內(nèi)部類本質(zhì)上是成員內(nèi)部類、局部內(nèi)部類的簡化寫法,這里將其統(tǒng)稱為內(nèi)部類。

 

責任編輯:趙寧寧 來源: 小z同學
相關推薦

2020-01-15 11:14:21

Java算法排序

2023-10-19 13:24:00

Java工具

2011-03-29 14:11:15

內(nèi)部類

2020-12-14 10:23:23

Java內(nèi)部類外部類

2021-02-08 08:45:18

Java內(nèi)部類Object類

2023-03-06 07:53:36

JavaN種內(nèi)部類

2009-06-11 13:08:29

Java內(nèi)部類Java編程思想

2019-12-23 14:32:38

Java內(nèi)部類代碼

2011-07-21 15:44:33

Java內(nèi)部類

2015-12-08 09:05:41

Java內(nèi)部類

2020-09-21 07:00:42

Java內(nèi)部類接口

2009-07-29 09:18:49

Java內(nèi)部類

2012-04-17 11:21:50

Java

2012-02-01 10:33:59

Java

2020-01-12 19:10:30

Java程序員數(shù)據(jù)

2015-10-26 09:25:42

2010-02-05 15:32:33

Java內(nèi)部類

2009-08-18 10:34:31

Java入門基本概念

2009-08-26 18:00:07

C#內(nèi)部類

2009-06-11 11:07:25

Java局部內(nèi)部類Final類型
點贊
收藏

51CTO技術棧公眾號