该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2004-11-01
我觉得写个接口更好一些,偷懒了没写
用户Client就用 Animal cat = new Cat();; cat.bark();; 就可以了 |
|
返回顶楼 | |
发表时间:2004-11-01
swing 写道 还是前面关于XML解析器的实现,
我们来深入一步好了, 假设你现在准备用一个实现乐org.w3c.dom 包的DOM实现,比如xerces, 这个时候你会去直接使用xerces中的Document接口实现类,还是说你通过org.w3c.dom提供的Document接口?我想是没有人关心xerces中是怎么实现Document接口的,甚至都不需要去关心到底那个实现类类名叫什么,你只要都依赖org.w3c.dom提供的接口,那么将来你就可以替换一个实现,比如出现了一个新的实现,它的效率是xerces的100000000倍,呵呵这个效率实在是难以抵抗的诱惑,你想替换,这个时候,如果你的代码(这里就是高层乐,高层是相对低层而言的)总是通过org.w3c.dom包的接口(这个包就是上面你所引用的一句话中的“抽象”乐)引用的,那么你只管替换实现包(这个就是低层实现乐)好了,你的代码不需要做任何改动, 但是你如果在你的代码中使用乐xerces实现中所独有的类,比如DocumentImp之类(注,我忘了那个实现类类名乐,差不多是这样大概,这里就不用较真乐我想),你就需要改你的代码乐。 到底是不是解耦乐,两个字: 显然 你不觉的自己的例子很无聊吗?你假设别人实现了某些功能,却发觉其有不足之处,但由于没有办法修改源代码,所以只好去继承原有类来实现新特性,按照你的说法,DIP的唯一用处就是亡羊补牢,不见的吧。 |
|
返回顶楼 | |
发表时间:2004-11-01
mikecool 写道 我觉得写个接口更好一些,偷懒了没写
用户Client就用 Animal cat = new Cat();; cat.bark();; 就可以了 老兄,仔细看看你的代码,和我的例子有本质区别吗,客户端的调用代码都是一模一样的,解藕的目的就是让客户端解除对具体类的依赖,管你抽象类和具体类自己内部怎么玩。 |
|
返回顶楼 | |
发表时间:2004-11-01
引用 你不觉的自己的例子很无聊吗?你假设别人实现了某些功能,却发觉其有不足之处,但由于没有办法修改源代码,所以只好去继承原有类来实现新特性,按照你的说法,DIP的唯一用处就是亡羊补牢,不见的吧。
晕哦,这里你又理解反乐,org.w3c.dom 包是我的高层接口, 我并不假设有人实现乐某些功能, 最关键的是,我不需要关心低层实现,这就是解耦。将来无论是我使用别人的代码,还是自己做一个实现,都不需要关心我到底拿这些实现做了什么, 你可以把这个抽象看成是高层和低层的约定,请注意这是代码级强制约定,所以对解耦非常有效。 本来想,XML的解析器应该是大家都比较熟悉的内容,所以才搬出来说,其实它本身是遵循有其它一些原则,单独讨论dip有些混乱。 另外: 引用 按照你的说法,DIP的唯一用处就是亡羊补牢
你这么说明显强词夺理,不知道该如何同你讨论乐,怎么说你也应该花时间精力真正理解我的话才好同我讨论,我不和你接着讨论乐,因为我不是来和你争的。 有一点奇怪,作者 正文 age0 你居然明白mikecool 的例子和你的没有本质区别,那为什么你还执着着你的例子?!! |
|
返回顶楼 | |
发表时间:2004-11-02
只能说他根本不懂什么叫抽象什么叫DIP,哎无知者无罪
无语 我的例子好像和Age0的还是不一样的吧。。。。竟然被看作一样的,我拿块豆腐撞死算了 |
|
返回顶楼 | |
发表时间:2004-11-02
^_^
原因很简单啊, 首先是你要给出高层接口,在你的例子里面,我想 你会把Animal作为高层接口, 但是,当你写下: Animal cat = new Cat(); 时,你说你不依赖Cat的代码,当然不可能乐。这样的话,你还不是把低层实现给参和进来乐?! 其实你只要考虑,为什么当你使用xerces的XML解析器实现时不需要关心里面的实现细节就知道怎么回事乐。 这里有2种显而易见的实现方式: 1、工厂,这是使用很普遍的方式 2、注入,这里说注入我想我只是借用乐一下词汇,感觉很形象,不一定是需要ioc的,比如: MyClass(Animal animal) { } 这样的构造器,还有普通的get/set方法等等。 经典的设计模式中大多数都是遵循dip原则的,当然,它们还有遵循其它原则。 |
|
返回顶楼 | |
发表时间:2004-11-02
我倒,这肯定是DIP几种标准不需知道细节的用法,我偷懒了,哎,只想用个简单例子写写好了
其实到头来都是还是:Animal a = new subclass of animal b();, 难道我在使用a的时候关心过b里面的细节么?我才不关心呢,我用的时候抽象出来的东西,子类爱怎么叫怎么叫啊:D 不论注入还是Factory都逃不过这一点,而且后来也还是用超类的一些方法来调用嘛,DocumentBuilderFactory也就这么做的。大可不必言必Factory IoC,毕竟这才是调用的本质嘛 继续拿头撞豆腐,呵呵玩笑 |
|
返回顶楼 | |
发表时间:2004-11-02
mikecool 写道 只能说他根本不懂什么叫抽象什么叫DIP,哎无知者无罪
无语 我的例子好像和Age0的还是不一样的吧。。。。竟然被看作一样的,我拿块豆腐撞死算了 谁规定了只有把类声明为abstract才叫抽象?abstract关键字发明前的oo都跟抽象搭不上关系?DIP原则和abstract关键字有什么必然的关系吗? |
|
返回顶楼 | |
发表时间:2004-11-02
swing 写道 ^_^
原因很简单啊, 首先是你要给出高层接口,在你的例子里面,我想 你会把Animal作为高层接口, 但是,当你写下: Animal cat = new Cat(); 时,你说你不依赖Cat的代码,当然不可能乐。这样的话,你还不是把低层实现给参和进来乐?! 其实你只要考虑,为什么当你使用xerces的XML解析器实现时不需要关心里面的实现细节就知道怎么回事乐。 这里有2种显而易见的实现方式: 1、工厂,这是使用很普遍的方式 2、注入,这里说注入我想我只是借用乐一下词汇,感觉很形象,不一定是需要ioc的,比如: MyClass(Animal animal) { } 这样的构造器,还有普通的get/set方法等等。 经典的设计模式中大多数都是遵循dip原则的,当然,它们还有遵循其它原则。 我一定要把cat的创建代码放到客户端里面,难道就不叫DIP了吗? class AnimalClient { Animal animal = null; public AnimalClient(string name); { switch(name); { case "猫": animal = new Cat();; break; case "狗": animal = new Dog();; default: animal = UnknownAnimal();; } } public void DoSometing(); { animal.Bark();; } } |
|
返回顶楼 | |
发表时间:2004-11-18
摇摇头,楼主举的例子只是为DIP而DIP,根本没有考虑使用DIP的Context,所以不具有任何批判性。
|
|
返回顶楼 | |