IClass a = new ClassA();
a.GetName();
你说你关心电是那个发电厂发的。
但是你的两条语句,就关心了。
假设,这两个语句是有不同的模块来使用就可以了。
a.GetName();
你说你关心电是那个发电厂发的。
但是你的两条语句,就关心了。
假设,这两个语句是有不同的模块来使用就可以了。
解决方案 »
- Devpress gridControl 棘手问题,求大家相助,跪谢了!!!
- 关于系统框架的搭建问题
- asp.net页中的事件触发疑惑
- 求一段完正的C#代码(access转化成sql2000)
- 菜鸟发问!
- VS 2010 调试时生成一个乱码的文件夹,项目文件是放在中文名的文件夹里的,VS是中文版的
- 谁现实这种功能?急啊,谢谢!!!!!!
- 为什么在winform中拖入了一个DataGrid,然后new了一个线程,在线程的执行过程中不能对DataGrid绑定数据源!
- 关于DataGrid的一个很难的问题!!
- 如何在左键菜单中增加一个带图标的文件夹,就像winrar或者winzip一样
- (求问)关于.NET的证书
- C# winform 皮肤设置后怎么改变背景色
啥意思,我没看懂?
我的意思是既然new的时候需要知道是哪个实现类,就说明没有办法屏蔽底层实现。
http://www.cnblogs.com/zhangzt/archive/2009/11/28/1612556.html
你上次那个问了3次也没结贴的问题就是太专注眼前,而非专注背后“管理类”
同样这个问题基本也是一个问题“依赖倒置---对抽象编程,对类型编程,而非要强求一个具体实现”
ok,我举个例子你就明白了
验孕纸====人家设计验孕纸只关心你提供的检测样本,而不关心你new了那个gril你站在验孕纸个这个设计的角度,你觉着你应该关心new了那个gril么?所以俺们不管gril是谁,俺们就管样本本身,俺们只依赖抽象,甚至俺们都可以假装一个gril都没有,只是理论上样本应该如此就可以设计这个纸片了
这里面讲的东西我都明白,我的意思是这里
IClass a = new ClassA();使用接口方法的时候,必须知道具体的实现类,而我们讲尽量屏蔽下层的实现,而你使用的时候又必须知道实现,岂不是违反了原则?
这里面讲的东西我都明白,我的意思是这里
IClass a = new ClassA();使用接口方法的时候,必须知道具体的实现类,而我们讲尽量屏蔽下层的实现,而你使用的时候又必须知道实现,岂不是违反了原则?
就拿你说的电厂来举例,我可以不知道电从哪里来,但是我起码得知道插座在哪里,是两项的还是三项的,是220V的还是110V的.
IClass a = new ClassA();这个也一样.我可以不去管CLASSA是从哪里来的,但是我必须知道我要实现的是什么,里面都有什么方法
你不需要知道对方给你的是A还是B,就能够用接口调用到它的内部实现这不挺好
GetName(IClass item) { reture item.GetName(); }如果没有接口或上层抽象,就可能需要这样写,因为item有可能是别的程序传给你的,你压根就不知道具体类型
GetName( object item)
{
if(item is A)
return (item as A).GetAName();
else if(item is B)
return (item as B).GetBName();
....
}
请问,从实际出发,如果我需要知道调用哪个实现的话,那么所谓的扩展是怎么实现的?我新定义一个方法也是一样的啊!你不用管是哪个电厂给你发电,是因为你不用直接调用电厂,而是供电局帮你new电厂。
相当于隔了1层,你---接口---供电局---接口---电厂。接口定义了规范,为什么要定义规范,就是为了减少变化,软件系统很怕变化。用了接口后,规范不变,但是实现可以变,大大增加了程序的弹性。
这样的做法本身没什么问题,也被广泛采用,
但是绝对不是什么依赖倒置,因为这样就必须要求提供者是XXX类型
依赖倒置是:由调用者实现接口,通过构造函数注入给提供者,提供者使用接口,
通过接口开放的事件,就能让提供者"随时"提供服务,而不需要由调用者显示调用提供者的方法
这样的话,就不需要知道提供者是什么类型了
比如电脑上有USB接口,电脑厂家只要定义好这个接口,设备厂家去实现这个接口
我这个USB就可以插入任何有USB的设备,然后你只要通过驱动告诉电脑你里面怎么调用,而电脑不需要知道设备里到底怎么实现的.否则就变成每个设备提供一个特定的类型,然后电脑要用就得安装不同的外部设备,变成一个怪物.
电厂的例子里,插座就是接口.你必须符合某种规范,不能就给我提供俩孔让我用两根电线去捅.
至于怎么用电,是后面的事,不用你操心。你也管不着。
这样的做法本身没什么问题,也被广泛采用,
但是绝对不是什么依赖倒置,因为这样就必须要求提供者是XXX类型
依赖倒置是:由调用者实现接口,通过构造函数注入给提供者,提供者使用接口,
通过接口开放的事件,就能让提供者"随时"提供服务,而不需要由调用者显示调用提供者的方法
这样的话,就不需要知道提供者是什么类型了
看来你也有点过于纠结了,不要一提依赖倒置就扯什么注入啊事件之类的
倒置是什么意思呢?
比如,电脑的USB接口,硬件厂商缺做的PS/2的接口,怎么办?
接口--基类--子类;
接口定义规范;基类包含你说的通用实现,非通用实现,可以写成抽象方法或者虚方法;子类不需要重写通用方法,只需要重写抽象方法或者虚方法。书上说的角度不同,着眼点不同,是从比较大的层面来说。你说的是比较小的实现。从高层次看,很多东西都是接口问题,api问题。
2.回答你的问题:
你设计这样一个接口,使得调用者和提供者在角色上反转,
这样的话,提供者成了接口的使用者,他是什么类型就无所谓了;
3.你那种写法作为编程手段无可厚非,但是不能作为设计手段,
很多人因为需要GetName这个方法,就弄个Iclass.GetName,这种接口只是编程意义上的接口,
而不是设计意义上的接口,它太具体了,没有什么重用价值,从而导致依赖这些接口的组件也没有重用价值,
不仅如此,到处都是接口还增加了代码量
不知道这是什么书。我想它非常容易产生误解。不管是interface还是class,只要是被你的class继承或者使用,你都可以看成是逻辑意义上的接口。只不过使用interface确实经常产生”痛苦“的体验,因为需要费力气去手写补充的一堆代码,不像class继承直接就自动化实现了。但是.net和java都不支持多重继承,因此很尴尬地是,假设一个class已经有父类class了,它就不可能再继承其它的class,你不得不只能让其使用其它的interface,才能实现面向对象的继承和多态特性。比如说 SqlDataReader,它继承了 DbDataReader,那么就无法继承 SqlDataRecord 类。于是只好尴尬地让 SqlDataReader 使用 IDataRecord,来达到能够多态地用于各种 DataRecord 应用类库的目的。显然这是费力的,但是这是历史造成的。是上个世纪末那个时代造成的。不能不成为微软首先选择了模仿java。
接口--基类--子类;
接口定义规范;基类包含你说的通用实现,非通用实现,可以写成抽象方法或者虚方法;子类不需要重写通用方法,只需要重写抽象方法或者虚方法。书上说的角度不同,着眼点不同,是从比较大的层面来说。你说的是比较小的实现。从高层次看,很多东西都是接口问题,api问题。根据我昨天一天的自我思考,也是采用了你说的这种方法:接口-基类-子类
不仅如此,我还想到了,如果基类如果给了实现,子类有可能不去实现的问题,后来又查找资料,得到一种解决方法:
基类关于接口的实现全部采用抽象函数,然后在基类中给一个默认的实现函数,在子类中调用基类的实现函数,这样还可以避免某些子类在不清楚的情况下,没有给予合适的实现。
2.回答你的问题:
你设计这样一个接口,使得调用者和提供者在角色上反转,
这样的话,提供者成了接口的使用者,他是什么类型就无所谓了;
3.你那种写法作为编程手段无可厚非,但是不能作为设计手段,
很多人因为需要GetName这个方法,就弄个Iclass.GetName,这种接口只是编程意义上的接口,
而不是设计意义上的接口,它太具体了,没有什么重用价值,从而导致依赖这些接口的组件也没有重用价值,
不仅如此,到处都是接口还增加了代码量算了,我说错了
我也没说我反对什么"顺序依赖";,我只是说LZ在理解的时候跳不出这个思维定式
恰恰相反,在实现开发中,我对接口的使用很谨慎,因为我也很懒
2.回答你的问题:
你设计这样一个接口,使得调用者和提供者在角色上反转,
这样的话,提供者成了接口的使用者,他是什么类型就无所谓了;
3.你那种写法作为编程手段无可厚非,但是不能作为设计手段,
很多人因为需要GetName这个方法,就弄个Iclass.GetName,这种接口只是编程意义上的接口,
而不是设计意义上的接口,它太具体了,没有什么重用价值,从而导致依赖这些接口的组件也没有重用价值,
不仅如此,到处都是接口还增加了代码量什么是设计意义上的接口?
myGate.送电(x);
I充电设备 y = new 电瓶车("YT-1");
myGate.送电(y);
原本就是这样使用接口的。除非你根本不去管最终应用方法,满脑子只有理论。
-----------
讲尽量屏蔽下层的实现,而你使用的时候又必须知道实现----------说法错误
-------------
接口其实是 3个方面:接口本身定义、接口的实现、接口的使用
IClass a = new ClassA() 是接口的使用,这里不存在你说的必须知道实现,这里还是不知道实现
实现是“inherit”。使用的“人”和实现(制造)的“人”不是一个人。你可以买个ClassA工厂的插座
IClass a = new ClassA() ;也可以买个 ClassB 工厂插座
IClass b = new ClassB() ;还可以买个 ClassC工厂 插座
IClass c = new ClassC() ;只要你买的规格参数一样,不论是 a,b,c ,你都可以使用那个标准的接口方法GetName来充电。
但你不知道 他内部到底怎么来实现的。