ChenGen

          一切歸零,重新開始
          隨筆 - 13, 文章 - 10, 評論 - 21, 引用 - 0
          數(shù)據(jù)加載中……

          控制反轉(zhuǎn)(Inverssion of Control,IoC)

          作者:Martin Fowler
          原文地址:http://martinfowler.com/bliki/InversionOfControl.html

          在擴展框架的時候,我們常常會遇到“控制反轉(zhuǎn)”這個現(xiàn)象,確實,它很多時候都被用來定義框架的特性。

          現(xiàn)在我們來考慮一個簡單的例子,假設我在寫一個通過命令行的方式從用戶那里獲取信息的程序,我的程序會這樣寫:

            #ruby
          puts 'What is your name?'
          name = gets
          process_name(name)
          puts 'What is your quest?'
          quest = gets
          process_quest(quest)

          在交互的過程中,我的程序處于控制狀態(tài):它決定何時問問題、何時給出回應、何時處理結(jié)果。

          然而,如果我通過窗口的方式來做,那么我會通過配置窗口來實現(xiàn):

            require 'tk'
          root = TkRoot.new()
          name_label = TkLabel.new() {text "What is Your Name?"}
          name_label.pack
          name = TkEntry.new(root).pack
          name.bind("FocusOut") {process_name(name)}
          quest_label = TkLabel.new() {text "What is Your Quest?"}
          quest_label.pack
          quest = TkEntry.new(root).pack
          quest.bind("FocusOut") {process_quest(quest)}
          Tk.mainloop()

          在控制流程上,這兩個程序有很大的不同,尤其在控制方法 process_name 和 process_quest 的調(diào)用上。在命令行的形式中,我的程序決定何時調(diào)用這些方法;而在使用窗口的例子中,則不是由我的程序來決定,我把控制交給了窗口系統(tǒng)(通過 Tk.mainloop 命令)。窗口系統(tǒng)基于我在創(chuàng)建窗口時所作的綁定來決定何時調(diào)用那些方法,所以控制被反轉(zhuǎn)了—不是有我的程序來調(diào)用窗口,而是由窗口來調(diào)用我的程序—這中現(xiàn)象就叫做“控制反轉(zhuǎn)”。

          框架的一個很重要的特性就是,用戶定義方法常常由框架自身來調(diào)用,而不是由用戶的代碼來調(diào)用。框架常常扮演主程序的角色來協(xié)調(diào)應用程序的活動。這種控制反轉(zhuǎn)是框架成為一個強大的可以擴展的骨架。用戶提供的方法對框架提供的一般性算法進行裁剪來提供更特殊的應用。--Ralph Johnson and Brian Foote

          控制反轉(zhuǎn)是使框架不同于庫的一個關(guān)鍵的部分。庫在本質(zhì)上是一系列你可以調(diào)用的方法,現(xiàn)在一般組織成類的形式,每次調(diào)用都會完成一些工作,然后將控制權(quán)返回給調(diào)用者。

          框架內(nèi)部嵌套了一些抽象的設計,有很多內(nèi)建表現(xiàn)。為了使用它,你需要通過繼承或者插件的方式將你的程序插入到框架的一些位置,然后框架會在這些地方調(diào)用你的代碼。

          有多種方法向框架插入你需要被調(diào)用的代碼。在上面的例子中,我們通過在在文本框上調(diào)用 bind 方法,同時將消息名稱作為參數(shù)傳給它,后面再跟一個用“{}”括起來的方法,來向框架插入代碼。當文本框檢測到一個消息的時候,就會調(diào)用在“{}”中的方法。使用“{}”是一中很方便的方式,但是很多編程語言都不支持這中方式。

          另一種方法是框架定義一些消息,然后在用戶代碼中注冊這些消息。.NET就是這樣一個平臺,它在語言方面擁有這樣的特性,可以讓用戶在窗口上定義一些消息,然后可以將方法綁定到這些消息上。

          上面的這些方法(他們實際上是相同的)在單個case上面工作得很好,但是有時候需要在單個單元擴展上面綁定多個方法的調(diào)用,在這種情況下,框架可以定義一個接口,用戶代碼通過實現(xiàn)這個接口來實現(xiàn)相關(guān)的調(diào)用。(這段話我也似懂非懂)

          EJBs是這種形式的控制反轉(zhuǎn)的一個很好的例子。當你在開發(fā)一個 session bean 的時候,你可以實現(xiàn)多個在不同生命周期點上被 EJB 容器調(diào)用的方法。例如,一個 Session Bean 接口定義了 ejbRemove、ejbPassivate和ejbActivate。你不需要關(guān)心這些方法什么時候被調(diào)用,而只需要關(guān)心它們做些什么。由容器來調(diào)用用戶的程序,而不是用戶的程序來調(diào)用容器。

          posted on 2007-04-10 15:50 ChenGen 閱讀(194) 評論(0)  編輯  收藏 所屬分類: spring


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導航:
           
          主站蜘蛛池模板: 松滋市| 大足县| 嘉善县| 汝南县| 天祝| 西乌| 晋宁县| 丽江市| 昌宁县| 日土县| 中方县| 木兰县| 盐池县| 息烽县| 乐山市| 永和县| 丹江口市| 沂水县| 姚安县| 淮北市| 县级市| 伊金霍洛旗| 灌云县| 凤凰县| 水城县| 工布江达县| 安乡县| 南川市| 镇巴县| 泽库县| 山阳县| 扶绥县| 博湖县| 鹤庆县| 西安市| 崇仁县| 蛟河市| 略阳县| 龙游县| 体育| 古蔺县|