What is Inversion of Control?

Inversion of Control (or IoC) can be quite confusing when it is first encountered.

  • What is it?
  • What problems does it solve?
  • When is it appropriate and when not?

  • The Inversion of Control (IoC) and Dependency Injection (DI) patterns are all about removing dependencies from your code.

    For example, say your application has a text editor component and you want to provide spell checking. Your standard code would look something like this:

    public class TextEditor {
    
        private SpellChecker checker;
    
        public TextEditor() {
            this.checker = new SpellChecker();
        }
    }
    

    What we've done here creates a dependency between the TextEditor and the SpellChecker . In an IoC scenario we would instead do something like this:

    public class TextEditor {
    
        private IocSpellChecker checker;
    
        public TextEditor(IocSpellChecker checker) {
            this.checker = checker;
        }
    }
    

    In the first code example we are instantiating SpellChecker ( this.checker = new SpellChecker(); ), which means the TextEditor class directly depends on the SpellChecker class.

    In the second code example we are creating an abstraction by having the SpellChecker dependency class in TextEditor constructor signature (not initializing dependency in class). This allows us to call the dependency then pass it to the TextEditor class like so:

    SpellChecker sc = new SpellChecker; // dependency
    TextEditor textEditor = new TextEditor(sc);
    

    Now the client creating the TextEditor class has the control over which SpellChecker implementation to use because we're injecting the dependency to the TextEditor signature.

    This is just a simple example, there's a good series of articles by Simone Busoli that explains it in greater detail.


    Inversion of Control is what you get when your program callbacks, eg like a gui program.

    For example, in an old school menu, you might have:

    print "enter your name"
    read name
    print "enter your address"
    read address
    etc...
    store in database
    

    thereby controlling the flow of user interaction.

    In a GUI program or somesuch, instead we say

    when the user types in field a, store it in NAME
    when the user types in field b, store it in ADDRESS
    when the user clicks the save button, call StoreInDatabase
    

    So now control is inverted... instead of the computer accepting user input in a fixed order, the user controls the order in which the data is entered, and when the data is saved in the database.

    Basically, anything with an event loop, callbacks, or execute triggers falls into this category.


    What is Inversion of Control?

    If you follow these simple two steps, you have done inversion of control:

  • Separate what -to-do part from when -to-do part.
  • Ensure that when part knows as little as possible about what part; and vice versa.
  • There are several techniques possible for each of these steps based on the technology/language you are using for your implementation.

    --

    The inversion part of the Inversion of Control (IoC) is the confusing thing; because inversion is the relative term. The best way to understand IoC is to forget about that word!

    --

    Examples

  • Event Handling. Event Handlers (what-to-do part) -- Raising Events (when-to-do part)
  • Interfaces. Component client (when-to-do part) -- Component Interface implementation (what-to-do part)
  • xUnit fixure. Setup and TearDown (what-to-do part) -- xUnit frameworks calls to Setup at the beginning and TearDown at the end (when-to-do part)
  • Template method design pattern. template method when-to-do part -- primitive subclass implementation what-to-do part
  • DLL container methods in COM. DllMain, DllCanUnload, etc (what-to-do part) -- COM/OS (when-to-do part)
  • 链接地址: http://www.djcxy.com/p/5116.html

    上一篇: MVC和MVVM有什么区别?

    下一篇: 什么是控制反转?