成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java 的雙重分發與 Visitor 模式

開發 開發工具 前端
談起面向對象的程序設計時,常說起的面向對象的「多態」,其中關于多態,經常有一個說法是「父類引用指向子類對象」。

[[235714]]

雙重分發(Double Dispatch)

什么是雙重分發?

談起面向對象的程序設計時,常說起的面向對象的「多態」,其中關于多態,經常有一個說法是「父類引用指向子類對象」。

這種父類的引用指向子類對象的寫法類似下面這種:

  1. Animal animal = new Dog(); 
  2. animal.bark(); 

另一種常用的形式是

  1.  public class Keeper { 
  2.   
  3.      public void say(Animal a) { 
  4.          System.out.println("Animal say"); 
  5.      } 
  6.   
  7.      public void say(Dog dog) { 
  8.          System.out.println("dog say"); 
  9.      } 
  10. Animal animal = new Animal(); 
  11. Animal dog = new Dog(); 
  12. Keeper keeper = new Keeper(); 
  13. keeper.say(animal); 
  14. keep.say(dog); 

那上面的keeper調用兩次say的時候,會輸出什么內容呢?會調用到兩個不同的方法嗎?

實際上在這兩次調用的時候,都會調用到say(Animal a)這個方法。由于這些內容在編譯期就能確實下來,這就是 Java 的 靜態分發。

從上面的圖我們看到,對于兩次調用生成的字節碼,確實都指向了say(Animal a)這個方法,運行時直接執行方法,輸出了對應的內容。

那對應的animal.bark() 為什么最終會調用到 dog 類的方法?這是在運行時確定具體的方法接收者的類型并執行。這就是所謂的動態分發,在運行時確定具體的方法,實現面向對象的多態。

分發(Dispatch)

分發就是指最終確定一個要執行的方法的過程。

對于 Java 等靜態語言來說,都是通過 單一分發(Single Dispatch)來進行的方法執行。

比如這樣一行代碼

  1. dog.eat(new Bone()) 

最終執行要選擇的eat方法,只會根據dog的具體類型選擇到對應的方法,而傳入的參數并不能影響到對應方法的選擇,這種就是 single Dispatch

為了讓傳入的真實參數,這里就是Bone來真正起到作用,就需要用到Double Dispatch或者叫做Multiple Dispatch

也就是說最終決定調用方法是哪一個的,不僅僅是方法的接收者,還受參數類型的決定。

Visitor 模式

在GoF 的設計模式中,Visitor 模式就使用到了Double Dispatch 達到了調用真實對象的目的。

對于Visitor 模式,最常用的例子是樹的遍歷。比如在處理到節點和樹葉時的方式有區別,此歸通過 visitor 的雙重分發,實現對于不同的 Element ,執行不同的內容。

代碼類似這樣:

  1. node.accept(new ConcreateVisitor()); 
  2. leaf.accept(new ConcreateVisitor()); 

node 中的 accept方法,會將自己的真實類型再次傳遞回visitor

  1. public void accept(Visitor v) { 
  2.     v.visit(this); 

此時,在visitor中,就能根據真實的類型來調用具體的方法,對應node 和 leaf 分別有類似這樣的方法:

  1. public void visit(Node n); 
  2. public void visit(Leaf l); 

Visitor 總結起來一般是包含 visitor 接口,在visitor 接口中,包含各個即將被訪問的 Element對象的處理邏輯。在 各個Element 的具體實現中,再將自己的類型傳遞回visitor 進行二次分發,實現確切邏輯的調用。

在Tomcat中的應用

Visitor 在Tomcat中也有應用,典型的是解析EL表達式。

比如org.apache.el.parser.Node

這個類中包含一個accept(NodeVisitor visitor)方法

實際的 Node 類型有很多,但在真實調用的這個時候,會通過

  1. public void accept(NodeVisitor visitor) throws Exception { 
  2.         visitor.visit(this); 

將真實類型傳回visitor, vistor中會調用具體的方法,從而實現參數也能起到決定作用的功能。

  1. public void visit(Node node) throws ELException { 
  2.         if (node instanceof AstFunction) { 
  3.  
  4.             AstFunction funcNode = (AstFunction) node; 
  5.  
  6.             Method m = null
  7.  
  8.            } else if (xxx) { 
  9.     } 

這里一般會聲明多個visit方法,然后上面的visit(this)會直接定位到目標方法上。

 

以上就是 Java 中的各類分發,以及 visitor這種模式通過模式的形式來實現雙重分發的效果。

【本文為51CTO專欄作者“侯樹成”的原創稿件,轉載請通過作者微信公眾號『Tomcat那些事兒』獲取授權】

戳這里,看該作者更多好文

責任編輯:趙寧寧 來源: 51CTO專欄
相關推薦

2013-12-23 09:48:43

C++鎖定模式

2023-03-14 07:31:17

EoscGo語言

2023-04-03 08:39:33

中間件go語言

2020-10-08 15:15:45

智能

2024-09-23 22:43:55

數據中臺數據飛輪數據處理

2017-06-01 08:17:20

HiriverMySQL數據

2013-07-24 10:03:15

2012-08-30 09:07:33

設計模式

2018-07-24 16:56:26

Docker,容器,鏡

2025-06-19 00:00:00

網絡安全DLP技術GenAI

2013-04-01 13:11:33

網絡CDN網絡加速

2009-07-08 09:32:25

Java設計模式

2023-10-31 17:49:22

2017-12-25 10:50:46

2013-08-22 11:28:15

百度應用模式

2022-10-25 12:41:03

智能建筑綠色建筑物聯網

2010-04-01 09:22:38

代理模式Java反射機制

2017-06-02 12:23:44

智能工廠物聯網制造業
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩欧美国产一区二区 | 久久高清亚洲 | 久久另类视频 | 美国av毛片| avtt国产 | 国产69久久精品成人看动漫 | 7777在线视频免费播放 | 国产综合av| 91网站在线看 | 欧美日韩在线一区二区 | 欧美日韩综合视频 | 国产成人精品一区二区三区在线 | 国产成人在线播放 | 2019天天干夜夜操 | www.黄色在线观看 | 亚洲精品久久久一区二区三区 | 亚洲美女网站 | 亚洲高清久久 | 欧美国产精品一区二区三区 | 青青草在线视频免费观看 | 日韩欧美三级在线 | 久在线| 国产成人精品一区二三区在线观看 | 精品一区二区在线观看 | 亚洲欧美在线免费观看 | 久久久视| 久久精品色欧美aⅴ一区二区 | 999精品视频| 欧美一区二区在线 | 亚洲先锋影音 | 日本精品一区二区三区视频 | 成人3d动漫一区二区三区91 | 亚洲 中文 欧美 日韩 在线观看 | 国产精品不卡一区二区三区 | 色婷婷av99xx| 日韩欧美视频在线 | 国产精品黄色 | 99久久日韩精品免费热麻豆美女 | 开操网 | a毛片视频网站 | 成人在线观看免费爱爱 |