控制反转(Inversion of Control,英文缩写为IoC)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题,也是轻量级的Spring框架的核心。 控制反转一般分为两种类型,依赖注入(Dependency Injection,简称DI)和依赖查找(Dependency Lookup)。依赖注入应用比较广泛。
一,那依赖注入有什么作用?
客户类和服务类之间存在的耦合,需要将耦合从代码中移出去,但是就存在客户类不可以实例化服务类,而客户类需要服务类的功能这一思考,这时我们就需要用到依赖注入的程序设计思路,在客户类定义一个注入点,用于服务类的注入,而客户类的UI层(创建实例层)负责根据情况,实例化服务类,注入到客户类中,从而解决了上面那个问题,最终目的是:让代码可维护。
二,现在我们来研究下,依赖注入的原理?
依赖注入(Dependency Injection):由于某客户类只依赖于服务类的一个接口,而不依赖于具体服务类,所以客户类只定义一个注入点。在程序运行过程中,客户类不直接实例化具体服务类实例,而是客户类的运行上下文环境或专门组件负责实例化服务类,然后将其注入到客户类中,保证客户类的正常运行。
而在理解依赖注入原理时:也同时理解下依赖倒置(Dependency Inversion Principle ):
1》高层模块不应该依赖低层模块,它们都应该依赖于抽象(即:客户类依赖于抽象接口层)
2》抽象不应该依赖于细节(具体的实现)。但细节应该依赖于抽象。(即:抽象接口具体实现类依赖于抽象接口层)
3》具体实现就是在UI层实例化抽象接口具体实现类注入到客户类,实现依赖注入
三,依赖注入的使用思路:
1》setter注入:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace RelyOnSetter { //依赖倒置,属性注入/setter注入实现方法,在当前实现实例并注入到People class Program { static void Main(string[] args) { People p = new People(); p.ispeak = new Chinese(); p.Say(); p.ispeak = new English(); p.Say(); Console.ReadKey(); } } //People依赖于接口ISpeak,在People中定义了一个注入点(ISpeak _iSpeak),属于高层依赖底层 public class People { public People() { } public ISpeak ispeak; public void Say() { this.ispeak.Say(); } } //抽象接口 public interface ISpeak { void Say(); } //接口具体实现依赖于抽象接口 public class Chinese : ISpeak { public void Say() { Console.WriteLine("中文"); } } //接口具体实现依赖于抽象接口 public class English : ISpeak { public void Say() { Console.WriteLine("英文"); } } }
2》构造注入:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace RelyOnStruct { //依赖倒置,构造注入实现方法,在当前实现实例并注入到People class Program { static void Main(string[] args) { People p = new People(new Chinese()); p.Say(); p = new People(new English()); p.Say(); Console.ReadKey(); } } //People依赖于接口ISpeak,在People中定义了一个注入点(ISpeak _iSpeak),属于高层依赖底层 public class People { public ISpeak _ispeak; public People(ISpeak ispeak) { this._ispeak = ispeak; } public void Say() { this._ispeak.Say(); } } //抽象接口 public interface ISpeak { void Say(); } //接口具体实现依赖于抽象接口 public class Chinese : ISpeak { public void Say() { Console.WriteLine("中文"); } } //接口具体实现依赖于抽象接口 public class English : ISpeak { public void Say() { Console.WriteLine("英文"); } } }
以上例子同时体现了依赖倒置的思路。
四,依赖注入是实现低耦合,那什么是低耦合和高内聚?
简单来说:耦合是程序模块之间的联系,内聚是程序模块内部的联系,低耦合就是模块之间的关联少,越独立耦合度越低,高内聚就是模块的内容针对干的事情少,功能越单一内聚越高
1》软件工程中对象之间的耦合度就是对象之间的依赖性。指导使用和维护对象的主要问题是对象之间的多重依赖性。对象之间的耦合越高,维护成本越高。因此对象的设计应使类和构件之间的耦合最小。
2》面向接口编程是面向对象编程思路中的一种,面向接口编程就是面向抽象接口,而不是面向具体实现类