依赖性 C#
近来看了一些外国人写的书籍,
发现了一个不太习惯的地方:
那就是他们写程序的时候喜欢写一个接口 , 比如:
public interface IProductRepository
{
IQueryable<Product> Products { get; }
void SaveProduct(Product product);
void DeleteProduct(Product product);
}//end interface
然后写一个具体的类来继承接口
public class EFProductRepository : IProductRepository
{
//具体不写了
}
最后就是将类模型绑定到 ninject 中
ninjectKernel.Bind<IProductRepository>().To<EFProductRepository>();
后面程序里面用的时候,就用:
IProductRepository repository这个就行了!!
我的问题是:为什么一开始不直接写具体的EFProductRepository , 用的时候就直接用EFProductRepository ,接口看起来很多余!
我看别人的说法是:使用di容器(比如刚才的ninject)可以保持松散耦合,什么叫松散耦合,什么叫依赖性啊??
[解决办法]
就是说比如
A调用B,那么A依赖B,如果我们需要让A调用C,那么就要修改A的代码。
class A
{
public void foo()
{
//B b = new B();
//b.bar();
C c = new C();
c.bar();
}
}
class B
{
public void bar()
{
...
}
}
class C
{
public void bar()
{
...
}
}
为什么我们要让A调用C?比如B是一个SQL Server数据库的访问层,C是一个MySQL的访问层,A是BLL,现在我们要替换实现,那么就需要修改A了。
我们希望A不修改,怎么办?
class A
{
Public I dal;
public void foo()
{
dal.bar();
}
}
interface I
{
void bar();
}
class B : I
{
public void bar()
{
...
}
}
class C : I
{
public void bar()
{
...
}
}
我们只要在实例化A的时候通过传递不同的I接口的对象(B或者C)就可以让A调用某个特定的实现而不用修改A 的代码了?
为什么我们那么在意修改A的代码?因为可能A是封装在一个dll中的。或者是另一个团队开发的。这在大型项目中很常见。
[解决办法]
我有一个方法,可以对所有的集合类型的数据进行处理,看起来是准格尔样子的:
public void ProcessSet(/*神秘的入参*/)
{
//......
}
它接收各种集合类型,比如:List, Collection, Hashtable, Array 等等等等。
我们可以为已知的现有集合类型创建每一个对应的方法(如果吃撑了的话),但是我们无法预料以后会有什么新的集合数据类型。所以我们必须对集合类型进行统一的“抽象”,即提取他们的共性,比如:Count()、Add()、Remove()、First()、Last() 等等。然后,对这一抽象的东西进行操作。这是一种行为特性上的非关联、非父子关系的抽象,这种抽象就叫接口(我自己的心得总结),什么意思呢?对于各种集合,他们之间存在必然的共性,但是他们之间又不都是不属于一类东西。所以抽象出 IEnumerable 接口,其中定义了各种集合操作需要用到的方法。然后:
public void ProcessSet(IEnumerable set)
{
//......
}
之后,对于所有的集合类,你这个方法都是通用的了。
这就是抽象,这就是接口的用处之一。有了这个,你的这个 ProcessSet 方法就“松耦合”了!耦合度松了,依赖度就随之降低!
[解决办法]
实在是在做小项目的时候,直接写EFProductRepository 会比较方便
大项目一般都会用先写接口,然后去实现接口的方式
[解决办法]
你说的是IOC,习惯写IOC模式的人,自然要这么写,习惯问题。IOC需要设计一个接口,调用时依赖接口注入真实对象类型来操作。人家养成了一个好的编程习惯,你可以学来用,也可以无视(水平不到别强求)
[解决办法]
如果你所有代码都一个思路,一个人写,那会觉得麻烦。
如果有很多人来共同完成,或者分很多模块,用接口的方式会发现扩展性的优势。
就那你的IProductRepository例子做扩展说明吧。
如果此系统只实现一个产品,那么这么写看起来是多余的,但是后期如果添加一个产品,那么此接口实现起来就简单了,为什么简单?具体说明下:一个系统保存和删除这个产品的地方(表单,业务流程等等)有非常多吧,大的系统可能有几百个地方调用这个方法,如果用接口的方式,添加一个产品,这些业务逻辑的地方一行代码都不需要修改,你只要具体实现新增加的这个产品方法就可以了,你也可以将这些代码全放在一个方法里面,那就要大量的判断语句了,造成代码的“耦合”了,就不清晰了。
[解决办法]
去看看大话设计模式吧,你会很有收获的。