内射老阿姨1区2区3区4区_久久精品人人做人人爽电影蜜月_久久国产精品亚洲77777_99精品又大又爽又粗少妇毛片

Java中雙重分發(fā)與Visitor模式的示例分析

這篇文章將為大家詳細(xì)講解有關(guān)Java中雙重分發(fā)與 Visitor模式的示例分析,小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

創(chuàng)新互聯(lián)公司成都網(wǎng)站建設(shè)按需定制,是成都網(wǎng)站營(yíng)銷推廣公司,為三維植被網(wǎng)提供網(wǎng)站建設(shè)服務(wù),有成熟的網(wǎng)站定制合作流程,提供網(wǎng)站定制設(shè)計(jì)服務(wù):原型圖制作、網(wǎng)站創(chuàng)意設(shè)計(jì)、前端HTML5制作、后臺(tái)程序開發(fā)等。成都網(wǎng)站維護(hù)熱線:18982081108

雙重分發(fā)(Double Dispatch)

什么是雙重分發(fā)?

談起面向?qū)ο蟮某绦蛟O(shè)計(jì)時(shí),常說(shuō)起的面向?qū)ο蟮摹付鄳B(tài)」,其中關(guān)于多態(tài),經(jīng)常有一個(gè)說(shuō)法是「父類引用指向子類對(duì)象」。

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

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

另一種常用的形式是

 public class Keeper { 
  public void say(Animal a) { 
   System.out.println("Animal say"); 
  } 
  public void say(Dog dog) { 
   System.out.println("dog say"); 
  } 
} 
Animal animal = new Animal(); 
Animal dog = new Dog(); 
Keeper keeper = new Keeper(); 
keeper.say(animal); 
keep.say(dog);

那上面的keeper調(diào)用兩次say的時(shí)候,會(huì)輸出什么內(nèi)容呢?會(huì)調(diào)用到兩個(gè)不同的方法嗎?

實(shí)際上在這兩次調(diào)用的時(shí)候,都會(huì)調(diào)用到say(Animal a)這個(gè)方法。由于這些內(nèi)容在編譯期就能確實(shí)下來(lái),這就是 Java 的 靜態(tài)分發(fā)。

Java中雙重分發(fā)與 Visitor模式的示例分析 

從上面的圖我們看到,對(duì)于兩次調(diào)用生成的字節(jié)碼,確實(shí)都指向了say(Animal a)這個(gè)方法,運(yùn)行時(shí)直接執(zhí)行方法,輸出了對(duì)應(yīng)的內(nèi)容。

那對(duì)應(yīng)的animal.bark() 為什么最終會(huì)調(diào)用到 dog 類的方法?這是在運(yùn)行時(shí)確定具體的方法接收者的類型并執(zhí)行。這就是所謂的動(dòng)態(tài)分發(fā),在運(yùn)行時(shí)確定具體的方法,實(shí)現(xiàn)面向?qū)ο蟮亩鄳B(tài)。

分發(fā)(Dispatch)

分發(fā)就是指最終確定一個(gè)要執(zhí)行的方法的過(guò)程。

對(duì)于 Java 等靜態(tài)語(yǔ)言來(lái)說(shuō),都是通過(guò) 單一分發(fā)(Single Dispatch)來(lái)進(jìn)行的方法執(zhí)行。
比如這樣一行代碼

dog.eat(new Bone())

最終執(zhí)行要選擇的eat方法,只會(huì)根據(jù)dog的具體類型選擇到對(duì)應(yīng)的方法,而傳入的參數(shù)并不能影響到對(duì)應(yīng)方法的選擇,這種就是 single Dispatch

為了讓傳入的真實(shí)參數(shù),這里就是Bone來(lái)真正起到作用,就需要用到Double Dispatch或者叫做Multiple Dispatch

也就是說(shuō)最終決定調(diào)用方法是哪一個(gè)的,不僅僅是方法的接收者,還受參數(shù)類型的決定。

Visitor 模式

在GoF 的設(shè)計(jì)模式中,Visitor 模式就使用到了Double Dispatch 達(dá)到了調(diào)用真實(shí)對(duì)象的目的。

對(duì)于Visitor 模式,最常用的例子是樹的遍歷。比如在處理到節(jié)點(diǎn)和樹葉時(shí)的方式有區(qū)別,此歸通過(guò) visitor 的雙重分發(fā),實(shí)現(xiàn)對(duì)于不同的 Element ,執(zhí)行不同的內(nèi)容。

代碼類似這樣:

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

node 中的 accept方法,會(huì)將自己的真實(shí)類型再次傳遞回visitor

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

此時(shí),在visitor中,就能根據(jù)真實(shí)的類型來(lái)調(diào)用具體的方法,對(duì)應(yīng)node 和 leaf 分別有類似這樣的方法:

public void visit(Node n); 
public void visit(Leaf l);

Visitor 總結(jié)起來(lái)一般是包含 visitor 接口,在visitor 接口中,包含各個(gè)即將被訪問(wèn)的 Element對(duì)象的處理邏輯。在 各個(gè)Element 的具體實(shí)現(xiàn)中,再將自己的類型傳遞回visitor 進(jìn)行二次分發(fā),實(shí)現(xiàn)確切邏輯的調(diào)用。
在Tomcat中的應(yīng)用

Visitor 在Tomcat中也有應(yīng)用,典型的是解析EL表達(dá)式。

比如org.apache.el.parser.Node

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

實(shí)際的 Node 類型有很多,但在真實(shí)調(diào)用的這個(gè)時(shí)候,會(huì)通過(guò)

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

將真實(shí)類型傳回visitor, vistor中會(huì)調(diào)用具體的方法,從而實(shí)現(xiàn)參數(shù)也能起到?jīng)Q定作用的功能。

public void visit(Node node) throws ELException { 
  if (node instanceof AstFunction) { 
   AstFunction funcNode = (AstFunction) node; 
   Method m = null; 
 
   } else if (xxx) { 
 }

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

關(guān)于“Java中雙重分發(fā)與 Visitor模式的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。

分享文章:Java中雙重分發(fā)與Visitor模式的示例分析
URL網(wǎng)址:http://www.rwnh.cn/article22/psghcc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)網(wǎng)站制作、靜態(tài)網(wǎng)站、網(wǎng)站設(shè)計(jì)公司、網(wǎng)站策劃企業(yè)建站、小程序開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設(shè)
博客| 文水县| 云和县| 仁布县| 池州市| 灵石县| 疏勒县| 乐亭县| 武山县| 康定县| 寿光市| 河北省| 汉寿县| 屏东市| 太原市| 建阳市| 探索| 同德县| 徐水县| 余姚市| 韶山市| 汨罗市| 民权县| 井冈山市| 漳浦县| 依安县| 泊头市| 和静县| 恭城| 邢台县| 额尔古纳市| 永和县| 丰顺县| 犍为县| 滨海县| 东乡| 剑河县| 鱼台县| 镇坪县| 禹城市| 油尖旺区|