一个好的软件架构应该是松耦合的,GOF的《设计模式》讲述了23种设计模式,为我们开发一个松耦合的软件架构提供了很大的帮助。
对于”对象的创建”,一个重要的模式就是”工厂模式”,但是由于工厂模式自身的一些缺陷(关于这点,可以参考这篇文章Inversion of control and Dependency injection
),变得越来越不流行,一种更好的替代方法就是IOC。
IOC,英语全称为Inversion of Control,翻译过来就是控制反转,讲白点就是控制权由主动变被动。
2004年,Martin Fowler在这篇文章中详细探讨了IOC的原理,并赋予IOC一个更贴切的名字Dependency Injection, 即DI,翻译过来就是依赖注入。
也就是说,获取对象的方式由原来的主动获取,变成由IOC容器注入。更确切一点讲,IOC是原理,DI道出了实现IOC的方式。
这里需要插入一个设计原则:依赖倒置原则(Dependence Inversion Principle:DIP)这个设计原则包括2点→
1)高层模块不应该依赖低层模块,二者都应该依赖抽象;
2)抽象不应该依赖具体实现,具体实现应该依赖抽象
在这里,所谓高层模块,是指业务性模块;低层模块是指细节类模块。
借用webcast》》设计模式纵横谈中的一个例子:人喝水
为了实现人拿杯子喝水,我们设计了如下类:
public class Person { public void DrinkWater(CeramicsCup cup) { cup.Drink(); } } public class CeramicsCup { public void Drink() { // the implement of drink by ceramics } }
如果哪一天,这个人要换杯子了,那就换呗:
public class Person { public void DrinkWater(GlassCup cup) { cup.Drink(); } } public class GlassCup { public void Drink() { // the implement of drink by glass } }
在这里,Person是高层模块,也是涉及到业务的模块,杯子是具体的细节,由于高层模块Person依赖了具体的杯子,导致了紧耦合。
如果按照DIP原则,我们的代码应该改成:
public class Person { public void DrinkWater(ICup cup) { cup.Drink(); } } public class CeramicsCup:ICup { public void Drink() { // the implement of drink by ceramics } } public class GlassCup:ICup { public void Drink() { // the implement of drink by glass } } public interface ICup { void Drink(); }
这样,不管是高层模块的Person,还是具体细节的杯子,都依赖于抽象出来的ICup。
IOC容器的实现正式依据上述原则来管理对象的创建和释放的。
目前,.net社区也提供了众多的IOC容器实现框架,包括Unity,Spring.Net, Castle等,我们在在这个系列中将使用Unity,这也是Enterprise Liberty所使用的IOC容器。