IoC: Inversion of Controlhtml
IoC是一种模式。目的是达到程序的复用。下面的两篇论文是对IoC的权威解释:java
一个对IoC形象化的描述,出自论文 http://www.digibarn.com/friends/curbow/star/XDEPaper.pdf 中的:编程
Don‘t call us, we’ll call you (Hollywood’s Law). A tool should arrange for Tajo to notify it when the user wishes to communicate some event to the tool, rather than adopt an “ask the user for a command and execute it” model.
当用户(人、程序)要使用一个工具的时候,让框架来激活这个工具,而不是让用户执行一些命令来激活它。segmentfault
即,原则是,使用组件的地方,只须要知道要使用什么样的组件,它会来自某个地方,但不须要知道组件具体是谁。api
按照这个原则开发的系统,实现了各组件之间相互依赖的解耦。即替换某个组件,不须要修改使用这个组件的组件。缓存
在编程语言实现上,IoC所涉及的工做主要有:oracle
IoC有不少具体的实现模式:框架
(1)Dependency Injection (DI) 依赖注入编程语言
组件管理器将组件注入到使用组件的对象中。函数
// Java示例:接口方法注入 // 注入依赖的接口 public interface InjectFinder { void injectFinder(MovieFinder finder); } // 注入依赖的接口 public interface InjectFinderFilename { void injectFilename(String filename); } // 注入器接口 public interface Injector { public void inject(Object target); } // == // 仅为InjectFinder组件 class MovieLister implements InjectFinder { public void injectFinder(MovieFinder finder) { this.finder = finder; } } // 既是InjectFinderFilename组件,又是InjectFinder接口的注入器 class ColonMovieFinder implements Injector, InjectFinderFilename { public void injectFilename(String filename) { this.filename = filename; } public void inject(Object target) { ((InjectFinder) target).injectFinder(this); } } // 仅为InjectFinderFilename接口的注入器 class FinderFilenameInjector implements Injector { public void inject(Object target) { ((InjectFinderFilename)target).injectFilename("movies1.txt"); } } // == class Tester { private Container container; private void configureContainer() { container = new Container(); // 注册组件。完成建立组件。 registerComponents(); // 注册注入器。完成组件注入。 registerInjectors(); container.start(); } private void registerComponents() { // 这里模式是 组件名 - 组件 container.registerComponent("MovieLister", MovieLister.class); container.registerComponent("MovieFinder", ColonMovieFinder.class); } private void registerInjectors() { // 这里的模式是 注入接口 - 注入器 // 容器会遍历全部的组件,若是组件实现了注入接口,将调用对应的注入器,将这个组件做为参数,传递给注入器 container.registerInjector(InjectFinder.class, container.lookup("MovieFinder")); container.registerInjector(InjectFinderFilename.class, new FinderFilenameInjector()); } public static void main(String[] args) { configureContainer(); MovieLister lister = (MovieLister)container.lookup("MovieLister"); Movie[] movies = lister.moviesDirectedBy("Sergio Leone"); assertEquals("Once Upon a Time in the West", movies[0].getTitle()); } }
(2)Service Locator 服务定位器
组件管理器将组件交给一个全局的服务者。组件的使用者主动向这个全局的服务者索取须要的组件。