问题描述
对控制(IOC)首次遇到时可能会令人困惑.
- 这是什么?
- 它解决了哪个问题?
- 什么时候适合使用?
每个DI实现都可以考虑IoC,但是不应将其称为IoC,因为实施依赖性注射要比回调要难(不要使用常规术语" IOC"来降低产品的价值而是).
为di示例,说您的应用程序具有文本编辑器组件,您想提供拼写检查.您的标准代码看起来像这样:
public class TextEditor { private SpellChecker checker; public TextEditor() { this.checker = new SpellChecker(); } }
我们在这里所做的工作在TextEditor和SpellChecker之间创造了一个依赖性. 在IOC方案中,我们会做这样的事情:
public class TextEditor { private IocSpellChecker checker; public TextEditor(IocSpellChecker checker) { this.checker = checker; } }
在第一个代码示例中,我们正在实例化SpellChecker(this.checker = new SpellChecker();),这意味着TextEditor类直接取决于SpellChecker类.
在第二个代码示例中,我们正在通过在SpellChecker的构造器签名中使用SpellChecker依赖项类(不在类中初始化依赖项)来创建抽象.这使我们能够调用依赖项,然后将其传递给TextEditor类,例如:
SpellChecker sc = new SpellChecker(); // dependency TextEditor textEditor = new TextEditor(sc);
现在,创建TextEditor类的客户端具有控制SpellChecker实现的控制,因为我们将依赖项注入TextEditor签名.
注意就像IOC是许多其他模式的基础一样,样本上方只是许多依赖注入类型之一,例如:
- 构造函数注入.
IocSpellChecker实例将传递给构造函数,无论是自动或与上述手动相似.
- 设置器注入.
IocSpellChecker实例将通过setter-method或public属性传递.
- Service-lookup和/或服务位置器
其中TextEditor会要求IocSpellChecker类型的全球使用者(服务)向已知的提供商询问(并且也许没有存储上述实例,而是一次又一次地询问提供商).
其他推荐答案
控制控制是您在程序回调时获得的,例如像GUI程序一样.
例如,在旧学校菜单中,您可能有:
print "enter your name" read name print "enter your address" read address etc... store in database
从而控制用户交互的流程.
在GUI程序或某些情况下,我们说:
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
因此,现在控制控制...而不是按固定顺序接受用户输入的计算机,而是控制输入数据的顺序,以及数据保存在数据库中时.
基本上,任何事件循环,回调或执行触发器属于此类别.
其他推荐答案
什么是控制反转?
如果您遵循以下两个步骤,则完成了控制的反转:
- 分开什么 - do零件与 - to-do part.
- 确保 零件在 中都知道 part;反之亦然.
根据您用于实施的技术/语言,这些步骤中的每个步骤都有几种技术.
-
倒置对控制反转(IOC)的一部分是令人困惑的事物.因为反转是相对项.理解IOC的最好方法是忘记这个词!
-
示例
- 事件处理.事件处理人员(何种零件) - 提高事件(何时完成部分)
- 依赖注射.构建依赖关系的代码(何种对零件) - 在需要时实例化和注入客户的依赖,通常由DI工具(例如Dagger)(何时完成)照顾.<<<<<<<<<<<<
- 接口.组件客户端(何时零件) - 组件接口实现(何种零件)
- Xunit固定装置.设置和拆卸(What-to-Do部分) - Xunit Frameworks在开始时呼叫设置,并在结束时(何时到达部分)
- 模板方法设计模式.模板方法何时到达零件 - 原始子类实现what-do-do part
- com中的dll容器方法. dllmain,dllcanunload等(What-to-do part) - com/os(何时到达零件)
问题描述
Inversion of Control (IoC) can be quite confusing when it is first encountered.
- What is it?
- Which problem does it solve?
- When is it appropriate to use and when not?
推荐答案
The Inversion-of-Control (IoC) pattern, is about providing any kind of callback, which "implements" and/or controls reaction, instead of acting ourselves directly (in other words, inversion and/or redirecting control to the external handler/controller). The Dependency-Injection (DI) pattern is a more specific version of IoC pattern, and is all about removing dependencies from your code.
Every DI implementation can be considered IoC, but one should not call it IoC, because implementing Dependency-Injection is harder than callback (Don't lower your product's worth by using the general term "IoC" instead).
For DI 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.
Note that just like IoC being the base of many other patterns, above sample is only one of many Dependency-Injection kinds, for example:
- Constructor Injection.
Where an instance of IocSpellChecker would be passed to constructor, either automatically or similar to above manually.
- Setter Injection.
Where an instance of IocSpellChecker would be passed through setter-method or public property.
- Service-lookup and/or Service-locator
Where TextEditor would ask a known provider for a globally-used-instance (service) of IocSpellChecker type (and that maybe without storing said instance, and instead, asking the provider again and again).
其他推荐答案
Inversion of Control is what you get when your program callbacks, e.g. 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)
- Dependency Injection. Code that constructs a dependency (what-to-do part) -- instantiating and injecting that dependency for the clients when needed, which is usually taken care of by the DI tools such as Dagger (when-to-do-part).
- Interfaces. Component client (when-to-do part) -- Component Interface implementation (what-to-do part)
- xUnit fixture. 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)