What is Inversion of Control?

前端 未结 30 2802
清歌不尽
清歌不尽 2020-11-22 00:13

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

  1. What is it?
  2. Which problem does it solve?
  3. When is it appropria
相关标签:
30条回答
  • 2020-11-22 00:24

    I like this explanation: http://joelabrahamsson.com/inversion-of-control-an-introduction-with-examples-in-net/

    It start simple and shows code examples as well.

    The consumer, X, needs the consumed class, Y, to accomplish something. That’s all good and natural, but does X really need to know that it uses Y?

    Isn’t it enough that X knows that it uses something that has the behavior, the methods, properties etc, of Y without knowing who actually implements the behavior?

    By extracting an abstract definition of the behavior used by X in Y, illustrated as I below, and letting the consumer X use an instance of that instead of Y it can continue to do what it does without having to know the specifics about Y.

    In the illustration above Y implements I and X uses an instance of I. While it’s quite possible that X still uses Y what’s interesting is that X doesn’t know that. It just knows that it uses something that implements I.

    Read article for further info and description of benefits such as:

    • X is not dependent on Y anymore
    • More flexible, implementation can be decided in runtime
    • Isolation of code unit, easier testing

    ...

    0 讨论(0)
  • 2020-11-22 00:25
    1. Wikipedia Article. To me, inversion of control is turning your sequentially written code and turning it into an delegation structure. Instead of your program explicitly controlling everything, your program sets up a class or library with certain functions to be called when certain things happen.

    2. It solves code duplication. For example, in the old days you would manually write your own event loop, polling the system libraries for new events. Nowadays, most modern APIs you simply tell the system libraries what events you're interested in, and it will let you know when they happen.

    3. Inversion of control is a practical way to reduce code duplication, and if you find yourself copying an entire method and only changing a small piece of the code, you can consider tackling it with inversion of control. Inversion of control is made easy in many languages through the concept of delegates, interfaces, or even raw function pointers.

      It is not appropriate to use in all cases, because the flow of a program can be harder to follow when written this way. It's a useful way to design methods when writing a library that will be reused, but it should be used sparingly in the core of your own program unless it really solves a code duplication problem.

    0 讨论(0)
  • 2020-11-22 00:28

    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's 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 control over which SpellChecker implementation to use because we're injecting the dependency into the TextEditor signature.

    0 讨论(0)
  • 2020-11-22 00:28

    Inversion of Control, (or IoC), is about getting freedom (You get married, you lost freedom and you are being controlled. You divorced, you have just implemented Inversion of Control. That's what we called, "decoupled". Good computer system discourages some very close relationship.) more flexibility (The kitchen in your office only serves clean tap water, that is your only choice when you want to drink. Your boss implemented Inversion of Control by setting up a new coffee machine. Now you get the flexibility of choosing either tap water or coffee.) and less dependency (Your partner has a job, you don't have a job, you financially depend on your partner, so you are controlled. You find a job, you have implemented Inversion of Control. Good computer system encourages in-dependency.)

    When you use a desktop computer, you have slaved (or say, controlled). You have to sit before a screen and look at it. Using the keyboard to type and using the mouse to navigate. And a badly written software can slave you even more. If you replace your desktop with a laptop, then you somewhat inverted control. You can easily take it and move around. So now you can control where you are with your computer, instead of your computer controlling it.

    By implementing Inversion of Control, a software/object consumer gets more controls/options over the software/objects, instead of being controlled or having fewer options.

    With the above ideas in mind. We still miss a key part of IoC. In the scenario of IoC, the software/object consumer is a sophisticated framework. That means the code you created is not called by yourself. Now let's explain why this way works better for a web application.

    Suppose your code is a group of workers. They need to build a car. These workers need a place and tools (a software framework) to build the car. A traditional software framework will be like a garage with many tools. So the workers need to make a plan themselves and use the tools to build the car. Building a car is not an easy business, it will be really hard for the workers to plan and cooperate properly. A modern software framework will be like a modern car factory with all the facilities and managers in place. The workers do not have to make any plan, the managers (part of the framework, they are the smartest people and made the most sophisticated plan) will help coordinate so that the workers know when to do their job (framework calls your code). The workers just need to be flexible enough to use any tools the managers give to them (by using Dependency Injection).

    Although the workers give the control of managing the project on the top level to the managers (the framework). But it is good to have some professionals help out. This is the concept of IoC truly come from.

    Modern Web applications with an MVC architecture depends on the framework to do URL Routing and put Controllers in place for the framework to call.

    Dependency Injection and Inversion of Control are related. Dependency Injection is at the micro level and Inversion of Control is at the macro level. You have to eat every bite (implement DI) in order to finish a meal (implement IoC).

    0 讨论(0)
  • 2020-11-22 00:28

    IoC is about inverting the relationship between your code and third-party code (library/framework):

    • In normal s/w development, you write the main() method and call "library" methods. You are in control :)
    • In IoC the "framework" controls main() and calls your methods. The Framework is in control :(

    DI (Dependency Injection) is about how the control flows in the application. Traditional desktop application had control flow from your application(main() method) to other library method calls, but with DI control flow is inverted that's framework takes care of starting your app, initializing it and invoking your methods whenever required.

    In the end you always win :)

    0 讨论(0)
  • 2020-11-22 00:29

    Programming speaking

    IoC in easy terms: It's the use of Interface as a way of specific something (such a field or a parameter) as a wildcard that can be used by some classes. It allows the re-usability of the code.

    For example, let's say that we have two classes : Dog and Cat. Both shares the same qualities/states: age, size, weight. So instead of creating a class of service called DogService and CatService, I can create a single one called AnimalService that allows to use Dog and Cat only if they use the interface IAnimal.

    However, pragmatically speaking, it has some backwards.

    a) Most of the developers don't know how to use it. For example, I can create a class called Customer and I can create automatically (using the tools of the IDE) an interface called ICustomer. So, it's not rare to find a folder filled with classes and interfaces, no matter if the interfaces will be reused or not. It's called BLOATED. Some people could argue that "may be in the future we could use it". :-|

    b) It has some limitings. For example, let's talk about the case of Dog and Cat and I want to add a new service (functionality) only for dogs. Let's say that I want to calculate the number of days that I need to train a dog (trainDays()), for cat it's useless, cats can't be trained (I'm joking).

    b.1) If I add trainDays() to the Service AnimalService then it also works with cats and it's not valid at all.

    b.2) I can add a condition in trainDays() where it evaluates which class is used. But it will break completely the IoC.

    b.3) I can create a new class of service called DogService just for the new functionality. But, it will increase the maintainability of the code because we will have two classes of service (with similar functionality) for Dog and it's bad.

    0 讨论(0)
提交回复
热议问题