乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      跨越邊界: 延遲綁定

       魚非魚 2007-03-28
      developerWorks
      文檔選項(xiàng)
      將此頁作為電子郵件發(fā)送

      將此頁作為電子郵件發(fā)送


      拓展 Tomcat 應(yīng)用

      下載 IBM 開源 J2EE 應(yīng)用服務(wù)器 WAS CE 新版本 V1.1


      級(jí)別: 中級(jí)

      Bruce Tate (bruce.tate@j2life.com), 總裁, RapidRed

      2006 年 12 月 18 日

      靜態(tài)類型語言(如 Java? 語言和 C)可以在編譯時(shí)把方法調(diào)用綁定到其實(shí)現(xiàn)中。這項(xiàng)策略讓這類語言可以執(zhí)行更豐富的語法和類型檢查。比起不具有此項(xiàng)編譯時(shí)檢查功能的動(dòng)態(tài)類型語言來說,靜態(tài)類型語言更加穩(wěn)定且具有更佳的性能。然而靜態(tài)類型語言存在一個(gè)嚴(yán)重的局限性:前期綁定。一些動(dòng)態(tài)類型語言(如 Ruby、Smalltalk 和 Self)允許延遲綁定,它們可以實(shí)現(xiàn)另一個(gè)層次的編程功能。

      幾年前,我有幸教我的大女兒學(xué)滑雪。滑雪學(xué)校提供的工具里有一條繩子,用這條繩把雪橇的尖端綁在一起。利用這根繩,初學(xué)滑雪的人能夠輕易地實(shí)現(xiàn)較為理想的滑雪動(dòng)作,如轉(zhuǎn)彎、減速和停止。最初,這些滑雪者十分依賴于這條繩子。我女兒還發(fā)誓說她離開這條繩就不滑雪。當(dāng)然,她這樣說是因?yàn)樗齽倓傞_始學(xué)所以對(duì)整個(gè)過程不了解。這沒關(guān)系。因?yàn)槲抑缹硭罱K會(huì)在滑雪時(shí)迫使自己沖破這一束縛。

      關(guān)于本系列

      當(dāng)今,非 Java 框架正在影響著 Java 框架的構(gòu)建方式。您從其他語言學(xué)到的概念可以影響 Java 編程,您所編寫的 Python(或 Ruby、Smalltalk 等語言)代碼也可以改變編寫 Java 代碼的方式。因此,在 跨越邊界 系列文章中,作者 Bruce Tate 提出這樣一種觀點(diǎn):即通過學(xué)習(xí)其他框架方法和語言,Java 開發(fā)人員可以更好地武裝自己!

      本專欄介紹與 Java 開發(fā)完全不同的編程概念和技術(shù),但這些概念和技術(shù)可以直接應(yīng)用于 Java 開發(fā)。在某些情況下,需要集成這些技術(shù)來利用它們;但在其他情況下,則可以直接應(yīng)用這些概念。在這里,單獨(dú)的工具并不重要,重要的是那些其他語言和框架中能夠影響 Java 社區(qū)開發(fā)人員、框架,甚至是基本方式的概念和思想。

      作為一名 Java 開發(fā)人員,我也有過類似的經(jīng)歷。我喜愛靜態(tài)類型提供的安全性。我曾和 Dave Thomas 就靜態(tài)類型檢查的優(yōu)點(diǎn)這個(gè)問題進(jìn)行過辯論,但我卻不能被說服。如果沒有最初的這條“安全之繩”,滑雪會(huì)是一種截然不同的體驗(yàn)。對(duì)于許多人來說,靜態(tài)類型也是一種依賴,這和雪橇上的束帶沒有什么區(qū)別。Dave 認(rèn)為我只是還沒有足夠的經(jīng)歷來理解動(dòng)態(tài)語言的好處罷了。當(dāng)我認(rèn)識(shí)到 Ruby 和 Smalltalk 的妙處之后,我開始明白對(duì)動(dòng)態(tài)類型我的確了解得不夠,但這也加深了我對(duì)它的理解(參閱之前的 跨越邊界 系列,獲取對(duì)靜態(tài)類型策略和動(dòng)態(tài)類型策略的總體比較)。對(duì)我來說它最大的好處是延遲綁定。本文使用 Ruby、Smalltalk 和一個(gè)叫做 Self 的 Smalltalk 的派生語言的編程例子探討了延遲綁定的好處。

      后期綁定和前期綁定

      編程語言能夠?qū)?duì)函數(shù)(或在面向?qū)ο笳Z言中的方法)的聲明從其調(diào)用中分離出來??梢月暶饕粋€(gè)方法并使用單獨(dú)的語法調(diào)用這個(gè)方法,但最終系統(tǒng)需要將這兩者綁到一起。將調(diào)用和實(shí)現(xiàn)綁到一起的過程叫做綁定。前期先綁定到類型再綁定到實(shí)現(xiàn),還是后期先綁定到類型再綁定到實(shí)現(xiàn),這對(duì)一門給定語言的編程體驗(yàn)來說有著顯著的影響。大多數(shù)面向?qū)ο蟮恼Z言都在后期綁定到實(shí)現(xiàn),從而允許多態(tài)性 ,該功能讓您能夠?qū)⒃S多不同的子類型表示為一種類型。Java 代碼和 C 主要在前期的一個(gè)編譯的步驟里綁定到一種類型。使用此策略,編譯器就有足夠的信息可以捕獲許多不同類型的 bug,比如說方法參數(shù)或返回值之間類型的不兼容。例如,清單 1 中的代碼就會(huì)產(chǎn)生幾個(gè)編譯錯(cuò)誤:


      清單 1. 編譯時(shí)綁定
      				...
                              x = 1.0 + anObject.methodThatReturnsString();
                              anObject.methodRequiringIntParameter(aString);
                              ...
                              

      通過編譯時(shí)捕獲錯(cuò)誤,前期綁定有助于在提早檢查出問題。對(duì)這種協(xié)助的價(jià)值存在很多質(zhì)疑。很明顯,類型檢查并不足以證明代碼的正確性。必需經(jīng)過測(cè)試,而這種測(cè)試所發(fā)現(xiàn)的問題也常常與類型有關(guān)。但這種協(xié)助是有代價(jià)的。使用前期綁定,編譯器必需對(duì)目標(biāo)對(duì)象的結(jié)構(gòu)作出如下假設(shè):

      • 必須有一個(gè)預(yù)定義好的有限方法列表。
      • 想要調(diào)用的方法必須在編譯時(shí)存在。
      • 必須綁定到已知的類型、接口或公共超類。
      • 綁定目標(biāo)的方法和屬性必須是固定的。

      這些假設(shè)所帶來的限制在最初也許并不明顯,但如果您再深入研究一下,很快就能發(fā)現(xiàn)后期綁定的益處,其中一些在跨越邊界 系列中已經(jīng)介紹過:

      • Ruby on Rails 的持久性框架 Active Record 含有不具有編譯時(shí)屬性的對(duì)象。建立了一個(gè)數(shù)據(jù)庫連接后,Rails 在運(yùn)行時(shí)為數(shù)據(jù)庫中的每一行添加一個(gè)屬性到該模型。Active Record 用戶并不總需要隨著數(shù)據(jù)模型的改變而改變模型對(duì)象。正是后期綁定讓這一切成為可能。

      • 單元測(cè)試員們必須經(jīng)常編寫代碼,這些代碼可以將測(cè)試實(shí)現(xiàn)(如 stub 或 mock)和產(chǎn)品實(shí)現(xiàn)綁定到相同的方法調(diào)用。Java 開發(fā)人員常使用叫做依賴性注入的設(shè)計(jì)模式來解決此問題,該模式常需要復(fù)雜的框架,如 EJB 或 Spring。這些框架雖然有很多優(yōu)勢(shì),但也帶來了相當(dāng)大的復(fù)雜性。面向方面的編程或有著依賴性查找的對(duì)象工廠也能解決該問題,但也同樣會(huì)增加復(fù)雜性。動(dòng)態(tài)語言中的測(cè)試框架(如 Smalltalk 和 Ruby)不需要依賴性注入框架,因?yàn)樗鼈兡軌蜻x擇在運(yùn)行時(shí)綁定到所需的實(shí)現(xiàn)。它們常常能夠用一小段代碼實(shí)現(xiàn)相同的目標(biāo)。

      • 整個(gè) Smalltalk 語言是構(gòu)建在延遲綁定的前提之下的。Smalltalk 開發(fā)人員在一個(gè)叫做 image 的持續(xù)運(yùn)行的應(yīng)用程序之上構(gòu)建。因?yàn)樗傇谶\(yùn)行,對(duì)任何類中方法的任何添加、刪除或更新操作都發(fā)生在運(yùn)行時(shí)。延遲綁定讓 Smalltalk 應(yīng)用程序在整個(gè)開發(fā)周期中可以持續(xù)運(yùn)行。

      連續(xù)區(qū)間

      靜態(tài)或動(dòng)態(tài)只是連續(xù)區(qū)間中的點(diǎn)。一些語言高度靜態(tài)。Java 語言比 C 或 C++ 更為動(dòng)態(tài)。連續(xù)區(qū)間中的每個(gè)點(diǎn)都有一套自已的折衷方式。Java 語言有許多有助于延遲綁定的功能,這些功能都以相對(duì)較高的復(fù)雜度為代價(jià)。反射、依賴性注入以及 XML 配置都可用于延遲綁定和減少耦合。一直以來,Java 語言都是通過添加功能(如面向方面編程)來使其更為動(dòng)態(tài)的。您也許會(huì)認(rèn)為 Java 開發(fā)人員擁有了所需的一切。但還有一類語言 —— 如 Smalltalk、Self 和 Ruby —— 要比 Java 還要?jiǎng)討B(tài)且允許用更佳的方式來延遲綁定。

      這些語言可以提供 Java 語言所沒有的技術(shù),如覆蓋在方法丟失時(shí)發(fā)生的行為。請(qǐng)記住,Java 語言需要存在用于編譯時(shí)綁定的方法。其他語言允許打開的類,這些類能夠基于開發(fā)人員需求進(jìn)行改變。如果您曾長久關(guān)注框架的發(fā)展,就會(huì)發(fā)現(xiàn)對(duì)延遲綁定的需求在日益增長,這種需求導(dǎo)致了 Java 語言中出現(xiàn)了許多很不自然的捆綁,它們使這門語言變得復(fù)雜且模糊。而其他語言則持觀望態(tài)度,等著我們?nèi)?gòu)建這類框架來實(shí)現(xiàn)更高的抽象級(jí)別以及更高的效率。對(duì)于您來說,好處很明顯:可以獲得一門更易表達(dá)且更高效的語言。

      為了理解連續(xù)區(qū)間中的點(diǎn),可以看一下反射的情況。使用 Java 語言,可以在運(yùn)行時(shí)裝載類,通過反射找到一個(gè)方法,為該方法驗(yàn)證正確的參數(shù)設(shè)置,然后執(zhí)行該方法。要實(shí)現(xiàn)這些功能很可能需要編寫很多代碼行。但為延遲綁定所做出的這些努力常常會(huì)得不償失,所以大多數(shù) Java 應(yīng)用程序開發(fā)人員不會(huì)使用此項(xiàng)技術(shù)。Ruby、Smalltalk 和 Self 都使用一種原操作(如 Ruby 中的 object.send(method_name))來完成此功能。該技術(shù)改變著這些語言中編程的本質(zhì),這樣的例子隨處可見。

      對(duì)類型策略和綁定策略越是深入研究就越會(huì)發(fā)現(xiàn):等到運(yùn)行時(shí)再綁定到調(diào)用或類型會(huì)根本性地改變編程的過程,從而開啟一個(gè)全新的可能世界。沒錯(cuò),您會(huì)發(fā)現(xiàn)這樣不那么安全。但您也會(huì)發(fā)現(xiàn):重復(fù)少了、功能強(qiáng)大了并且在減少代碼行的同時(shí)有了更大的靈活性。為了理解這一切是如何運(yùn)行的,下面將快速介紹一下 Smalltalk、Self 和 Ruby。首先介紹延遲綁定調(diào)用方法,然后介紹一些可以在運(yùn)行時(shí)改變類定義的可用技術(shù)。





      回頁首


      延遲調(diào)用

      在靜態(tài)語言中,編譯器在編譯時(shí)直接將調(diào)用綁定到實(shí)現(xiàn)。動(dòng)態(tài)語言則有些不同。Ruby、Smalltalk 和 Self 依賴于消息傳送來延遲綁定。客戶機(jī)使用消息傳送來指定目標(biāo)對(duì)象、消息和參數(shù)集。這完全是一個(gè)運(yùn)行機(jī)制。所以動(dòng)態(tài)語言有效地添加了一級(jí)間接尋址。它們將消息名綁定到一個(gè)對(duì)象上,而不是從調(diào)用綁定到類型再到實(shí)現(xiàn)。然后,將該對(duì)象綁定到一個(gè)名稱或標(biāo)記,并使用該名稱或標(biāo)記在運(yùn)行時(shí)查找相關(guān)的實(shí)現(xiàn)。它是這樣工作的:

      1. 客戶機(jī)向目標(biāo)對(duì)象發(fā)送一條消息。
      2. 該消息有一個(gè)名稱和零個(gè)或多個(gè)參數(shù)。
      3. 該目標(biāo)(可以是類或?qū)ο螅┎檎沂欠裼信c此消息同名的方法。
      4. 如果有,目標(biāo)對(duì)象調(diào)用該方法。
      5. 如果沒有,目標(biāo)對(duì)象向父對(duì)象發(fā)送一條消息。父對(duì)象可能是一個(gè)超類(Smalltalk)、一個(gè)父對(duì)象(Self)或一個(gè)模塊(Ruby)。
      6. 如果在任何父對(duì)象中都沒找到該方法,會(huì)調(diào)用一個(gè)錯(cuò)誤捕捉方法。

      上述所有步驟都發(fā)生在運(yùn)行時(shí) 。這意味著在執(zhí)行該消息的語句前,既不需要目標(biāo)方法,也不需要實(shí)現(xiàn)。在 Smalltalk 中,一切皆是對(duì)象,且大多數(shù)行為都利用消息傳送。甚至于控制結(jié)構(gòu)都依賴它。Smalltalk 有三種消息:一元消息(無參數(shù))、二元消息(帶固定的參數(shù)集)和關(guān)鍵字消息(帶已命名的參數(shù))。例如:

      • 7 sin 將一元消息 sin 發(fā)送給目標(biāo)對(duì)象 7。
      • 3 + 4 是一條二元消息。它將帶參數(shù) 4+ 消息發(fā)送給對(duì)象 3。
      • array at: 1 put "value". 是一條關(guān)鍵字消息。該代碼將消息 at: put: 發(fā)送到 array 對(duì)象,將 value 放置在數(shù)組中 1 的位置。
      • condition ifTrue: [doSomething] ifFalse: [doSomethingElse]. 是一條關(guān)鍵字消息。括號(hào)中的代碼叫做閉包代碼塊 。這個(gè)代碼樣例將 :ifTrue :ifFalse 消息發(fā)送到 condition 對(duì)象。如果條件為真,Smalltalk 執(zhí)行 [doSomething] 代碼塊;否則執(zhí)行 [doSomethingElse] 代碼塊。

      Ruby 支持消息傳送和直接方法調(diào)用。Ruby 中的消息傳送看起來有些許不同,但前提是一致的。在清單 2 中,定義了帶 speak 方法和 sleep 方法的 Dog 類。直接調(diào)用 speak 方法并通過 send 方法按 name 調(diào)用 sleep 方法。


      清單 2. 在 Ruby 中用兩種方式調(diào)用方法
                              irb(main):001:0> class Dog
                              irb(main):002:1>   def speak
                              irb(main):003:2>     puts "Arf"
                              irb(main):004:2>   end
                              irb(main):005:1>   def sleep
                              irb(main):006:2>     puts "Zzz"
                              irb(main):007:2>   end
                              irb(main):008:1> end
                              => nil
                              irb(main):009:0> dog = Dog.new
                              => #<Dog:0x34fa9c>
                              irb(main):010:0> dog.speak
                              Arf
                              => nil
                              irb(main):011:0> message = "sleep"
                              => "sleep"
                              irb(main):012:0> dog.send message
                              Zzz
                              

      如果您是一名 Java 程序員,這些都不是什么新鮮內(nèi)容。您當(dāng)然可以通過 Java 的反射 API 處理后期綁定。只是需要更多的努力來實(shí)現(xiàn)同樣的功能。但用任意字符串(可以通過編程進(jìn)行修改)調(diào)用方法確實(shí)打開了語言中一項(xiàng)額外的功能。最為重要的是,能夠輕易地調(diào)用在運(yùn)行時(shí)過后所添加的任意行為。

      Self 語言將消息傳送這一概念發(fā)揮到極致。在 Self 中,一切皆是對(duì)象。通過消息傳送專門地調(diào)用所有 Self 行為。Self 不含類(通過復(fù)制其他對(duì)象創(chuàng)建新對(duì)象)也不含變量(只有帶方法和對(duì)象的已命名的 slot)。Self 使用消息傳送來調(diào)用已命名的 slot 和方法。其他大多數(shù)面向?qū)ο蟮恼Z言通過允許直接訪問實(shí)例數(shù)據(jù)弱化了封裝的價(jià)值,但 Self 通過加強(qiáng)用于訪問方法和實(shí)例數(shù)據(jù)的相同協(xié)議克服了這一不足。發(fā)送一條消息調(diào)用一個(gè) slot。如果一個(gè) slot 有一個(gè)對(duì)象,該對(duì)象返回其值。Self 對(duì)訪問屬性和訪問方法不作區(qū)別。這項(xiàng)簡化措施讓 Self 成為了一門簡單但功能卻很強(qiáng)大的編程語言。像 Smalltalk 一樣,Self 用消息傳送來表示控制結(jié)構(gòu),Self 依賴于一個(gè)一直運(yùn)行的 image。Self 中的對(duì)象都有一個(gè)父對(duì)象以及包含其他對(duì)象或方法的 slot。從 Self 對(duì)消息傳送的嚴(yán)重依賴以及 Self 應(yīng)用程序一直運(yùn)行這一概念可以看出:延遲綁定是 Self 的中心課題。

      Self 中的消息傳送和 Smalltalk 中的幾乎一樣。在 Smalltalk 中 count <- 3 將數(shù)字 3 賦給一個(gè)叫做 count 的變量。但 Self 沒有變量,也沒有賦值。需要發(fā)送消息 object count: 3objectcount slot 的值設(shè)置為 3。要檢索 count 的值,只需簡單地使用 object count。

      當(dāng)您將 method_missing 加入進(jìn)來后,消息傳送就有了另一層次的意義。請(qǐng)記住,這項(xiàng)功能對(duì)于動(dòng)態(tài)語言來說是開放的,可對(duì)于在編譯時(shí)綁定到類型的語言來說卻是徹底關(guān)閉的。前期綁定的好處(強(qiáng)迫該方法必須存在)原來也是其核心的弱點(diǎn)。Ruby 讓您能夠越過 method_missing 行為來調(diào)用在運(yùn)行時(shí)也許不存在的方法的行為。Active Record 將類和表關(guān)聯(lián)起來,并按照數(shù)據(jù)庫中的每一列給每個(gè)類動(dòng)態(tài)地添加一個(gè)屬性。Active Record 也為每個(gè)列或列的集合自動(dòng)添加尋找程序!例如,映射到 people 數(shù)據(jù)庫表的 Person 類具有 first_namelast_name 列,person.find_by_first_name_and_last_name 是一個(gè)合法的 Active Record 語句,盡管這樣的方法并不存在。 Active Record 越過 method_missing 并在運(yùn)行時(shí)解析該方法名以確定該方法名是否有效。結(jié)果就會(huì)產(chǎn)生一個(gè)相當(dāng)有效的框架用于包裝數(shù)據(jù)庫表,該框架通過后期綁定而獲得了極大的簡化。但到目前為止,我還只是探討了有關(guān)調(diào)用的內(nèi)容?,F(xiàn)在可以討論一下有關(guān)添加行為的話題了。





      回頁首


      在運(yùn)行時(shí)添加行為

      所有這三種語言(Self、Smalltalk 和 Ruby)都使在運(yùn)行時(shí)添加行為變得十分簡單。使用 Self 和 Smalltalk,對(duì)現(xiàn)有類所做的任何更改都是通過定義一個(gè)運(yùn)行時(shí)修改來實(shí)現(xiàn)的。當(dāng)添加一個(gè)方法時(shí),也有效地修改了一個(gè)活動(dòng)的類。在 Self 中添加或刪除 slot 很簡單:只需要發(fā)送 _add_slot 消息。類似地,在 Smalltalk 中,可以通過調(diào)用相應(yīng)的消息(在一些地方稱作 compile)來添加方法或?qū)傩?。在這兩種情況下,都可以直接在 image 中修改類的單個(gè)副本。接下來我要對(duì) Ruby 中對(duì)類添加行為進(jìn)行稍微深入一點(diǎn)的探討。

      Ruby 框架常使用在運(yùn)行時(shí)通過幾種不同的機(jī)制修改類的技術(shù)。最簡單的是打開類??梢源蜷_任何的 Ruby 類,并通過重命名、添加或刪除方法或?qū)傩詠砀乃<僭O(shè)您想要在 Ruby 中擴(kuò)展數(shù)字來簡化柱狀圖的實(shí)現(xiàn)過程。您可以打開 Fixnum 類,并添加一個(gè)方法來打印出相應(yīng)長度的柱,如清單 3 所示。


      清單 3. 擴(kuò)展 Fixnum
                              irb(main):001:0> 7.class
                              => Fixnum
                              irb(main):002:0> class Fixnum
                              irb(main):003:1>   def bar
                              irb(main):004:2>     puts(‘-‘*self)
                              irb(main):005:2>   end
                              irb(main):006:1> end
                              => nil
                              irb(main):007:0> 7
                              => 7
                              irb(main):008:0> 7.bar
                              -------
                              => nil
                              irb(main):009:0> [6, 8, 2, 4, 9].each {|i| i.bar}
                              ------
                              --------
                              --
                              ----
                              ---------
                              => [6, 8, 2, 4, 9]
                              

      這個(gè)例子展示了當(dāng)您在運(yùn)行程序時(shí)知道了該行為后該如何擴(kuò)展 Ruby 類。當(dāng)想要基于未知規(guī)則給一個(gè)類添加任意行為時(shí),則需要使用一項(xiàng)不同的技術(shù)??梢栽陬惖纳舷挛闹泄烙?jì)字符串。以清單 4 為例。清單 3 擴(kuò)展了 Fixnum 類,該類被認(rèn)為是靜態(tài)的。在清單 4 中,該類根本不需要被認(rèn)為是靜態(tài)的。對(duì) Dog 的擴(kuò)展讓您可以添加任意行為到 dog 或任何其他類中。該類打開自己,添加進(jìn)一個(gè)具有您指定的名稱的方法,并添加您指定給該類的行為:


      清單 4. 可擴(kuò)展的類
                              class Dog
                              def self.extend(method_name, method_body)
                              class_eval(%Q[
                              def #{method_name}
                              #{method_body}
                              end
                              ])
                              end
                              def speak
                              puts "Arf"
                              end
                              end
                              dog = Dog.new
                              Dog.extend("sneeze", "puts ‘Achoo!‘")
                              dog.speak
                              dog.sneeze
                              

      清單 4 中的 extend 方法還需要進(jìn)一步加以說明。這里大概地解釋一下。Ruby 打開一個(gè)類并添加一個(gè)帶有您提供給 Dog 類的名稱及主體的方法。首先,定義一個(gè)叫做 self.extend 的方法。self. 意味著 extend 是一個(gè)類方法,即在整個(gè)類上操作的方法,比如 new 方法。其次,調(diào)用 class_eval。這個(gè)方法打開類并在打開的類上執(zhí)行下列字符串。接下來,所有在 %[] 之間的代碼都被解釋為單個(gè)的字符串。最后,Ruby 按 #{} 之間的變量替代了該值。





      回頁首


      現(xiàn)狀和超越

      在清單 4 的例子中,從內(nèi)部擴(kuò)展了 Dog。采用相同的技術(shù),可以用相同的方式擴(kuò)展任意的 Ruby 類?,F(xiàn)在,延遲綁定全部的能量就凸現(xiàn)了出來??梢詾橐粋€(gè)普通的類擴(kuò)展任意的功能并調(diào)用類的新行為,盡管當(dāng)編寫原始類時(shí)它們根本不存在。

      反射的功能也不能不提。Self、Ruby 和 Smalltalk 通常都進(jìn)行反射。其消息傳送功能允許不迫使用戶訪問物理的方法就調(diào)用方法,正如在 Java 語言中那樣。class.methods 提供 Ruby 中一組方法名的數(shù)組,而 class methods 可以返回 Smalltalk 中的方法集。使用這些功能及類似的特性幾乎可以找到在類或?qū)ο笊线M(jìn)行快速自檢所需的一切。

      到目前為止,我主要探討了關(guān)于綁定到方法的內(nèi)容,但延遲綁定的內(nèi)容要多得多??匆幌虑鍐?5 中所示的 Ruby 的方法定義。


      清單 5. 添加兩個(gè)數(shù)字
                              def add(x, y)
                              x+y
                              end
                              

      如果采用類似的 Java 方法,就需要鍵入?yún)?shù)。這個(gè) Ruby 方法返回兩個(gè)數(shù)字的和。使用該方法惟一的要求是:第一個(gè)對(duì)象實(shí)現(xiàn) + 而第二個(gè)對(duì)象和第一個(gè)要兼容。該方法的客戶機(jī)能夠確定對(duì)象是否兼容。

      類似的 Java 方法只適用于單一類型的參數(shù)。而這個(gè) Ruby 方法能夠服務(wù)于浮點(diǎn)型、整型、字符串型以及任何支持 + 方法的類型。延遲綁定可以讓單個(gè)的方法具有真正的多態(tài)性。該設(shè)計(jì)也是可擴(kuò)展的,因?yàn)樗軌蛑С之?dāng)前系統(tǒng)尚未實(shí)現(xiàn)的類型。例如,此方法可以輕易地支持虛數(shù)。





      回頁首


      用 Java 語言延遲綁定

      Java 社區(qū)對(duì)靜態(tài)類型檢查的迷戀程度令人驚訝,Java 程序員們正在不遺余力地尋找延遲綁定的方式。有些方法是成功的。諸如 Spring 等框架的存在主要是為了延遲綁定,它有助于減緩客戶機(jī)和服務(wù)之間的耦合。面向方面的編程通過提供能夠擴(kuò)展類的功能(甚至可以超出其當(dāng)前的功能)的服務(wù)來實(shí)現(xiàn)延遲綁定。像 Hibernate 這樣的框架也可以延遲綁定,通過反射、代理和其他工具在運(yùn)行時(shí)將持久性功能添加到純粹、普通的 Java 對(duì)象(POJO)中?,F(xiàn)在有很多關(guān)于如何用 POJO 編程的流行書籍可供開發(fā)人員參考,這些書籍大多會(huì)使用愈加復(fù)雜的技術(shù)(比反射還要先進(jìn)),而這些技術(shù)主要是為了打開類并延遲綁定,從而有效地回避了靜態(tài)類型。

      在其他地方,延遲綁定的方法就不那么成功。依賴于 XML 來延遲綁定的部署描述符有很多問題。對(duì) XML 的過分依賴和我們對(duì)語言中的動(dòng)態(tài)行為的強(qiáng)烈渴望有很大關(guān)系,因?yàn)檫@些語言常常有點(diǎn)太過靜態(tài),綁定得有點(diǎn)太早,并且有點(diǎn)太受限制。

      現(xiàn)在已經(jīng)有一些語言和技術(shù)可以為 Java 程序員們極想解決的這幾類問題提供解決方案,例如透明的持久性、為可測(cè)試性減少耦合、更加豐富的插件模型等。只要看看推動(dòng) Java 持久性框架發(fā)展的元程序設(shè)計(jì),并同 Active Record、Gemstone 或 Og(動(dòng)態(tài)語言中的持久性框架)中類似的解決方案對(duì)比一下,一切就一目了然了(參見 參考資料)。現(xiàn)在延遲綁定變得越來越重要,并且推動(dòng)該過程的那些思想和做法在其它語言中也甚為高效。當(dāng)您需要進(jìn)行元程序設(shè)計(jì)時(shí),請(qǐng)打開您的工具箱,加入幾種允許延遲綁定的語言。不要害怕跨越邊界!



      參考資料

      學(xué)習(xí)
      • 您可以參閱本文在 developerWorks 全球站點(diǎn)上的 英文原文 。

      • Java To Ruby: Things Your Manager Should Know (Tate,Pragmatic Bookshelf,2006 年 ):本文作者編著的一本書,講述了在何時(shí)何地需要從 Java 編程轉(zhuǎn)變到 Ruby on Rails 以及如何完成這種轉(zhuǎn)變。

      • Beyond Java (Tate,O‘Reilly,2005 年):本文作者編著的一本書,講述了 Java 語言的起源及穩(wěn)定發(fā)展,以及在某些方面能夠挑戰(zhàn) Java 平臺(tái)的技術(shù)。

      • Og:Ruby 中的一個(gè)對(duì)象-關(guān)系映射器。由于 Active Record 的流行,它并沒有發(fā)展起來,但其使用模型卻很引人注目。

      • Gemstone:流行的 Smalltalk 數(shù)據(jù)庫。

      • Smalltalk.org:Smalltalk 的社區(qū)站點(diǎn)。

      • Rails Up and Running (Tate,O‘Reilly,2006 年):本文作者編著的一本關(guān)于 Ruby on Rails 的入門書。

      • Book review: Agile Web Development with Rails ” (Darren Torpey,developerWorks,2005 年 5 月):介紹了這樣一本書,它可以加深讀者對(duì) Rails 和敏捷開發(fā)方式原理的理解。

      • Spring Framework:Spring 是一個(gè)克服了 Java 語言中靜態(tài)類型局限性的出色的框架。

      • Programming Ruby (Dave Thomas et al.,Pragmatic Bookshelf,2005 年):關(guān)于 Ruby 編程的一本暢銷書。

      • The Rails API:Rails 框架文檔,該文檔是有關(guān) Active Record 及其實(shí)現(xiàn)技術(shù)的出色的參考資料。

      • Java 技術(shù)專區(qū):數(shù)百篇關(guān)于 Java 編程各個(gè)方面的文章。


      獲得產(chǎn)品和技術(shù)
      • Squeak:由 Disney 開發(fā)的一個(gè) Smalltalk 實(shí)現(xiàn)。

      • Self:下載 Self 編程語言,該語言是 Smalltalk 的簡化版。

      • Ruby on Rails:下載開源的 Ruby on Rails Web 框架。

      • Ruby:從項(xiàng)目 Web 站點(diǎn)獲取 Ruby。


      討論

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多