隨筆-9  評論-168  文章-266  trackbacks-0

           IoC全名Inversion of Control,如果中文硬要翻譯過來的話,就是「控制反轉」。初看IoC,從字面上不容易瞭解其意義,我覺得要瞭解IoC,要先從Dependency Inversion開始瞭解,也就是依賴關係的反轉。

           Dependency Inversion在下面這篇文章中有了清楚的解釋:
          http://www.objectmentor.com/publications/dip.pdf

           簡單的說,在模組設計時,高層的抽象模組通常是與業務相關的模組,它應該具有重用性,而不依賴於低層的實作模組,例如如果低層模組原先是軟碟存取模式,而高層模組是個存檔備份的需求,如果高層模組直接叫用低層模組的函式,則就對其產生了依賴關係。

          舉個例子,例如下面這個程式:

          #include <floppy.h>
          ....
          void save() {
          ....
          saveToFloppy()
          }
          }

           由於save()程式依賴於saveToFloppy(),如果今天要更換低層的存儲模組為Usb碟,則這個程式沒有辦法重用,必須加以修改才行,低層模組的更動造成了高層模組也必須跟著更動,這不是一個好的設計方式,我們希望模組都依賴於模組的抽象,這樣才可以重用高層的業務設計。

           如果以物件導向的方式來設計,依賴反轉(Dependency Inversion)的解釋變為程式不應依賴實作,而是依賴於抽象,實作必須依賴於抽象。我們來看看下面這個Java程式:

          BusinessObject.java
          public class BusinessObject {
          private FloppyWriter writer = new FloppyWriter();
          ....
          public void save() {
          ...
          writer.saveToFloppy();
          }
          }

           在這個程式中,BusinessObject的存檔依賴於實際的FloppyWriter,如果今天我們想要將存檔改為存至Usb碟,我們必須修改或繼承BusinessObject進行擴展,而無法直接使用BusinessObject。

          如果透過介面的宣告,可以改進此一情況,例如:

          public interface IDeviceWriter {
          public void saveToDevice();
          }
          public class BusinessObject {
          private IDeviceWriter writer;
          public void setDeviceWriter(IDeviceWriter writer) {
          this.writer = writer;
          }
          public void save() {
          ....
          writer.saveToDevice();
          }
          }

           這樣一來,BusinessObject就是可重用的,如果今天我有存儲至Floppy或Usb碟的需求,我只要實作IDeviceWriter即可,而不用修改BusinessObject:

          public class FloppyWriter implement IDeviceWriter {
          public void saveToDevice() {
          ....
          // 實際儲存至Floppy的程式碼
              }
          }
          public class UsbDiskWriter implement IDeviceWriter {
          public void saveToDevice() {
          ....
          // 實際儲存至UsbDisk的程式碼
              }
          }

           從這個角度來看,Dependency Inversion的意思即是程式不依賴於實作,而是程式與實作都要依賴於抽象。

           IoC的Control是控制的意思,其實其背後的意義也是一種依賴關係的轉移,如果A依賴於B,其意義即是B擁有控制權,我們要轉移這種關係,所以依賴關係的反轉即是控制關係的反轉,藉由控制關係的轉移,我們可以獲得元件的可重用性,在上面的Java程式中,整個控制權從實際的 FloppyWriter轉移至抽象的IDeviceWriter介面上,使得BusinessObject、FloppyWriter、 UsbDiskWriter這幾個實現依賴於抽象的IDeviceWriter介面。

           從容器(Container)的角度,程式的業務邏輯部份應是可以重用的,不應受到所使用框架或容器的影響,因為我們可能轉移整個業務邏輯至其它的框架或容器,如果業務邏輯過於依賴容器,則轉移至其它的框架或容器時,就會發生困難。

           IoC在容器的角度,可以用這麼一句好萊塢名言來代表:"Don't call me, I'll call you." 以程式的術語來說的話,就是「不要向容器要求您所需要的(物件)資源,容器會自動將這些物件給您!」。IoC要求的是容器不侵入應用程式本身,應用程式本身提供好介面,容器可以透過這些介面將所需的資源注至程式中,應用程式不向容器主動要求資源,故而不會依賴於容器的元件,應用程式本身不會意識到正被容器使用,可以隨時從容器中脫離轉移而不用作任何的修改,而這個特性正是一些業務邏輯中間件最需要的。


                                                                       -------------[轉http://www.javaworld.com.tw Added by 良葛格, last edited by Forth on Aug 13, 2005  (view change) ]

          posted on 2007-10-30 11:12 紫蝶∏飛揚↗ 閱讀(465) 評論(0)  編輯  收藏 所屬分類: Spring
          <2025年5月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          常用鏈接

          留言簿(5)

          隨筆檔案(9)

          文章分類(339)

          文章檔案(265)

          最新隨筆

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 稻城县| 孟津县| 兴安县| 通城县| 高平市| 芦山县| 榆中县| 天柱县| 长白| 丘北县| 香河县| 澄城县| 义马市| 赣榆县| 肃北| 永顺县| 六安市| 城市| 无棣县| 松桃| 石城县| 嘉峪关市| 苍溪县| 平罗县| 佳木斯市| 阿拉善盟| 惠东县| 堆龙德庆县| 五台县| 剑河县| 积石山| 翼城县| 朝阳县| 长兴县| 南安市| 五莲县| 辽源市| 交口县| 麟游县| 蓬溪县| 宜阳县|