1. 程式人生 > 其它 >Inversion of control

Inversion of control

Inversion of control

From Wikipedia, the free encyclopedia Jump to navigationJump to search

Insoftware engineering,inversion of control(IoC) is a programming principle. IoC inverts theflow of controlas compared to traditional control flow. In IoC, custom-written portions of acomputer programreceive the flow of control from a generic

framework. Asoftware architecturewith this design inverts control as compared to traditionalprocedural programming: in traditional programming, the custom code that expresses the purpose of the programcallsinto reusable libraries to take care of generic tasks, but with inversion of control, it is the framework that calls into the custom, or task-specific, code.

Inversion of control is used to increasemodularityof the program and make itextensible,[1]and has applications inobject-oriented programmingand otherprogramming paradigms. The term was used by Michael Mattsson in a thesis,[2]taken from there[3]by Stefano Mazzocchi and popularized by him in 1999 in a defunct Apache Software Foundation project,

Avalon, then further popularized in 2004 byRobert C. MartinandMartin Fowler.

The term is related to, but different from, thedependency inversion principle, which concerns itself withdecoupling dependenciesbetweenhigh-level and low-levellayersthrough sharedabstractions. The general concept is also related toevent-driven programmingin that it is often implemented using IoC so that the custom code is commonly only concerned with the handling of events, whereas theevent loopand dispatch of events/messages is handled by the framework or the runtime environment.

Contents

Overview[edit]

As an example, with traditional programming, themain functionof an application might make function calls into a menu library to display a list of availablecommandsand query the user to select one.[4]The library thus would return the chosen option as the value of the function call, and the main function uses this value to execute the associated command. This style was common intext based interfaces. For example, anemail clientmay show a screen with commands to load new mail, answer the current mail, start a new mail, etc., and the program execution would block until the user presses a key to select a command.

With inversion of control, on the other hand, the program would be written using asoftware frameworkthat knows common behavioral and graphical elements, such aswindowing systems, menus, controlling the mouse, and so on. The custom code "fills in the blanks" for the framework, such as supplying a table of menu items and registering a code subroutine for each item, but it is the framework that monitors the user's actions and invokes the subroutine when a menu item is selected. In the mail client example, the framework could follow both the keyboard and mouse inputs and call the command invoked by the user by either means, and at the same time monitor thenetwork interfaceto find out if new messages arrive and refresh the screen when some network activity is detected. The same framework could be used as the skeleton for a spreadsheet program or a text editor. Conversely, the framework knows nothing about Web browsers, spreadsheets or text editors; implementing their functionality takes custom code.

Inversion of control carries the strong connotation that the reusable code and the problem-specific code are developed independently even though they operate together in an application.Callbacks,schedulers,event loops,dependency injection, and thetemplate methodare examples ofdesign patternsthat follow the inversion of control principle, although the term is most commonly used in the context ofobject-oriented programming.

Inversion of control serves the following design purposes:

  • Todecouplethe execution of a task from implementation.
  • To focus a module on the task it is designed for.
  • To free modules from assumptions about how other systems do what they do and instead rely oncontracts.
  • To preventside effectswhen replacing a module.

Inversion of control is sometimes facetiously referred to as the "Hollywood Principle: Don't call us, we'll call you".

Background[edit]

Inversion of control is not a new term in computer science.Martin Fowlertraces the etymology of the phrase back to 1988,[5]but it is closely related to the concept ofprogram inversiondescribed byMichael Jacksonin hisJackson Structured Programmingmethodology in the 1970s.[6]Abottom-up parsercan be seen as an inversion of atop-down parser: in the one case, the control lies with the parser, while in the other case, it lies with the receiving application.

Dependency injectionis a specific type of IoC.[4]Aservice locatorsuch as theJava Naming and Directory Interface(JNDI) is similar. In an article by Loek Bergman,[7]it is presented as an architectural principle.

In an article byRobert C. Martin,[8]the dependency inversion principle and abstraction by layering come together. His reason to use the term "inversion" is in comparison with traditional software development methods. He describes the uncoupling of services by the abstraction of layers when he is talking about dependency inversion. The principle is used to find out where system borders are in the design of the abstraction layers.

Description[edit]

In traditional programming, theflowof thebusiness logicis determined by objects that arestatically boundto one another. With inversion of control, the flow depends on the object graph that is built up during program execution. Such a dynamic flow is made possible by object interactions that are defined through abstractions. Thisrun-time bindingis achieved by mechanisms such asdependency injectionor aservice locator. In IoC, the code could also be linked statically during compilation, but finding the code to execute by reading its description fromexternal configurationinstead of with a direct reference in the code itself.

In dependency injection, a dependentobjector module is coupled to the object it needs atrun time. Which particular object will satisfy the dependency during program execution typically cannot be known atcompile timeusingstatic analysis. While described in terms of object interaction here, the principle can apply to other programming methodologies besidesobject-oriented programming.

In order for the running program to bind objects to one another, the objects must possess compatibleinterfaces. For example, classAmay delegate behavior to interfaceIwhich is implemented by classB; the program instantiatesAandB, and then injectsBintoA.

Implementation techniques[edit]

Inobject-oriented programming, there are several basic techniques to implement inversion of control. These are:

In an original article by Martin Fowler,[9]the first three different techniques are discussed. In a description about inversion of control types,[10]the last one is mentioned. Often the contextualized lookup will be accomplished using a service locator

Examples[edit]

Most frameworks such as.NETorEnterprise Javadisplay this pattern:

public class ServerFacade {
    public <K, V> V respondToRequest(K request) {
        if (businessLayer.validateRequest(request)) {
            Data data = DAO.getData(request);
            return Aspect.convertData(data);
        }
        return null;
    }
}

This basic outline in Java gives an example of code following the IoC methodology. It is important, however, that in theServerFacadea lot of assumptions are made about the data returned by thedata access object(DAO).

Although all these assumptions might be valid at some time, they couple the implementation of theServerFacadeto the DAO implementation. Designing the application in the manner of inversion of control would hand over the control completely to the DAO object. The code would then become

public class ServerFacade {
    public <K, V> V respondToRequest(K request, DAO dao) {
        return dao.getData(request);
    }
}

The example shows that the way the methodrespondToRequestis constructed determines if IoC is used. It is the way that parameters are used that define IoC. This resembles themessage-passingstyle that some object-oriented programming languages use.

控制反轉
維基百科,自由的百科全書
跳轉到導航跳轉到搜尋
在軟體工程中,控制反轉 (IoC) 是一種程式設計原則。與傳統控制流相比,IoC 反轉了控制流。在 IoC 中,計算機程式的自定義編寫部分從通用框架接收控制流。與傳統的過程程式設計相比,具有這種設計的軟體架構顛倒了控制:在傳統程式設計中,表達程式目的的自定義程式碼呼叫可重用的庫來處理通用任務,但在控制反轉時,它是框架呼叫自定義或特定於任務的程式碼。

控制反轉用於增加程式的模組化並使其可擴充套件,[1] 並在面向物件程式設計和其他程式設計正規化中得到應用。該術語由 Michael Mattsson 在一篇論文中使用,[2] 取自 Stefano Mazzocchi 的論文 [3],並於 1999 年在一個已不復存在的 Apache 軟體基金會專案 Avalon 中推廣,然後在 2004 年由 Robert C. Martin 和馬丁福勒。

該術語與依賴倒置原則有關,但與依賴倒置原則不同,後者涉及通過共享抽象解耦高層和低層之間的依賴關係。一般概念也與事件驅動程式設計有關,因為它通常使用 IoC 實現,因此自定義程式碼通常只關注事件的處理,而事件迴圈和事件/訊息的排程由框架或執行時環境。


內容
1 概述
2 背景
3 說明
4 實現技術
5個例子
6 另見
7 參考文獻
8 外部連結
概述
例如,在傳統程式設計中,應用程式的主要功能可能會將函式呼叫到選單庫中,以顯示可用命令列表並詢問使用者選擇一個。[4]因此,庫將返回所選選項作為函式呼叫的值,並且主函式使用該值來執行關聯的命令。這種風格在基於文字的介面中很常見。例如,電子郵件客戶端可能會顯示一個螢幕,其中包含載入新郵件、回覆當前郵件、開始新郵件等命令,並且程式執行將一直阻塞,直到使用者按下某個鍵來選擇命令。

另一方面,通過控制反轉,程式將使用瞭解常見行為和圖形元素(例如視窗系統、選單、控制滑鼠等)的軟體框架編寫。框架的自定義程式碼“填空”,例如提供選單項表併為每個專案註冊程式碼子例程,但它是框架監視使用者的操作並在選擇選單項時呼叫子例程.在郵件客戶端示例中,該框架可以同時跟蹤鍵盤和滑鼠輸入並通過任何一種方式呼叫使用者呼叫的命令,同時監視網路介面以找出新訊息是否到達並在某些時候重新整理螢幕。檢測到網路活動。相同的框架可以用作電子表格程式或文字編輯器的框架。相反,該框架對 Web 瀏覽器、電子表格或文字編輯器一無所知。實現它們的功能需要自定義程式碼。

控制反轉具有很強的含義,即可重用程式碼和特定於問題的程式碼是獨立開發的,即使它們在應用程式中一起執行。回撥、排程程式、事件迴圈、依賴注入和模板方法是遵循控制反轉原則的設計模式的示例,儘管該術語最常用於面向物件程式設計的上下文中。

控制反轉用於以下設計目的:

將任務的執行與實現分離。
將模組集中在其設計的任務上。
將模組從關於其他系統如何做他們所做的假設中解放出來,而是依賴於契約。
防止更換模組時產生副作用。
控制反轉有時被戲稱為“好萊塢原則:不要打電話給我們,我們會打電話給你”。

背景
控制反轉並不是電腦科學中的新術語。 Martin Fowler 將這個短語的詞源追溯到 1988 年,[5] 但它與邁克爾傑克遜在 1970 年代在他的傑克遜結構化程式設計方法中描述的程式反轉概念密切相關。 [6]自底向上解析器可以看作是自頂向下解析器的反轉:在一種情況下,控制權屬於解析器,而在另一種情況下,它屬於接收應用程式。

依賴注入是一種特定型別的 IoC。[4]服務定位器(例如 Java 命名和目錄介面 (JNDI))與此類似。在 Loek Bergman 的一篇文章中,[7] 它是作為一種架構原則提出的。

Robert C. Martin 的一篇文章[8] 將依賴倒置原理和分層抽象結合在一起。他使用“反轉”一詞的原因是與傳統的軟體開發方法進行比較。當他談論依賴倒置時,他通過層的抽象描述了服務的解耦。該原理用於找出抽象層設計中系統邊界的位置。

描述
在傳統程式設計中,業務邏輯的流向由相互靜態繫結的物件決定。通過控制反轉,流程取決於在程式執行期間建立的物件圖。通過抽象定義的物件互動使這種動態流成為可能。這種執行時繫結是通過依賴注入或服務定位器等機制實現的。在 IoC 中,程式碼也可以在編譯期間靜態連結,但通過從外部配置讀取其描述而不是直接引用程式碼本身來找到要執行的程式碼。

在依賴注入中,依賴物件或模組在執行時與它需要的物件耦合。在程式執行期間,哪個特定物件將滿足依賴性通常無法在編譯時使用靜態分析知道。雖然這裡是根據物件互動來描述的,但該原理可以應用於除面向物件程式設計之外的其他程式設計方法。

為了讓正在執行的程式將物件相互繫結,物件必須具有相容的介面。例如,類 A 可以將行為委託給由類 B 實現的介面 I;程式例項化 A 和 B,然後將 B 注入 A。

實現技術
在面向物件程式設計中,有幾種基本技術可以實現控制反轉。這些是:

使用服務定位器模式
使用依賴注入,例如
建構函式注入
引數注入
二傳手注入
介面注入
使用上下文查詢
使用模板方法設計模式
使用策略設計模式
在 Martin Fowler 的一篇原創文章中,[9] 討論了前三種不同的技術。在關於控制型別反轉的描述中,[10] 提到了最後一個。通常上下文查詢將使用服務定位器完成

例子
大多數框架(例如 .NET 或 Enterprise Java)都顯示這種模式:

公共類 ServerFacade {
public <K, V> V respondToRequest(K 請求) {
如果(businessLayer.validateRequest(請求)){
資料資料 = DAO.getData(request);
返回 Aspect.convertData(data);
}
返回空;
}
}
Java 中的這個基本大綱提供了一個遵循 IoC 方法的程式碼示例。然而,重要的是,在 ServerFacade 中,對資料訪問物件 (DAO) 返回的資料做出了許多假設。

儘管所有這些假設在某些時候可能是有效的,但它們將 ServerFacade 的實現與 DAO 實現耦合。以控制反轉的方式設計應用程式會將控制權完全交給 DAO 物件。然後程式碼會變成

公共類 ServerFacade {
public <K, V> V respondToRequest(K request, DAO dao) {
返回 dao.getData(request);
}
}
該示例顯示方法 respondToRequest 的構造方式決定了是否使用 IoC。它是使用引數定義 IoC 的方式。這類似於某些面向物件的程式語言使用的訊息傳遞風格。

如有錯誤,懇求讀者指出,傳送到[email protected]