本文承接 使用面向对象重构之-把抽象控制在一处:提高内聚性。
上次遗留的问题是,使用了工厂模式重构之后,创建工厂对象的位置依然没有确定。
...
public interface IStaffFactory<T> where T: StaffBase{
T CreateStaff();
}
public class StaffFactory: IStaffFactory<LocalStaff>{
public LocalStaff CreateStaff();
}
public class TravelStaff: IStaffFactory<TravelStaff>{
public TravelStaff CreateStaff();
}
...
本文要强调的就是依赖注入,和大多数项目一样,可以选择一种DI框架来完成依赖注入。一般DI的过程分两部分,一个是定义,一个是注入。几乎每个Prj都会选择程序启动的位置来做依赖注入。下面以.net中的Unit框架为例。
1. 定义要做DI的接口
public interface IStaffFactory<T> where T: StaffBase{
T CreateStaff();
}
public class StaffFactory: IStaffFactory<LocalStaff>{
public LocalStaff CreateStaff();
}
public class TravelStaffFactory: IStaffFactory<TravelStaff>{
public TravelStaff CreateStaff();
}
public class StaffPerformance{
[InjectionConstructor]
public StaffCateen(IStaffFactory<TravelStaff> staffFactory){
}
}
2. 在程序启动时注入 (以控制台程序为例):
static void Main(string[] args)
{
IUnityContainer unitycontainer = new UnityContainer();
unitycontainer.RegisterType<IStaffFactory<LocalStaff>, StaffFactory>();
unitycontainer.RegisterType<IStaffFactory<TravelStaff>, TravelStaffFactory>();
var performance = unitycontainer.Resolve<StaffPerformance>();
Console.ReadLine();
}
其他DI框架。
除了Unit,.net还有很多优秀的DI框架,比如NInject,还有轻量的Autofac。
总结,依赖注入是对代码最外层的实例与接口进行解耦,在面向对象的编程中并不是必须的,不过是目前做IOC比较普遍的一种方案。
依赖注入并不是要替代所有的实例化,过度使用会产生性能问题。
对象创建在项目中要根据面向对象的原则而灵活设计,哪个类承担什么责任,要非常清晰。类责任过小,则会违背Information Expert原则,降低内聚性并导致调用责任分散从而造成多处依赖;类责任过大的问题更多了,对他类耦合高,低内聚,并且很可能会违背开闭原则。
总之,依赖注入是实现IOC的手段,IOC是实现依赖反转(依赖抽象而非具体)的手段,而依赖本身是否稳定,是最重要的。