找回密码
 FreeOZ用户注册
查看: 3600|回复: 33
打印 上一主题 下一主题

[论坛技术] 实际写代码 interface, design pattern用的多么?

[复制链接]
跳转到指定楼层
1#
发表于 26-4-2010 13:37:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
提示: 作者被禁止或删除, 无法发言

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?FreeOZ用户注册

x
看看这个例子,
http://www.asp.net/learn/mvc/tutorial-29-cs.aspx

原来变成很简单啊,一路写下去,后来因为一些代码重用,就搞几个函数。
怎么现在把代码搞得这么复杂啊,为了减小耦合性,分离出这么多层,又是interface,又是service的。
看上边的例子,搞出那么多多余的东西。

学术上倒是看起来舒服了,可是整个代码变得好复杂啊。我想问,实际开发中,项目组对于这些Design Pattern应用的实际情况如何。
回复  

使用道具 举报

2#
发表于 26-4-2010 13:57:14 | 只看该作者
这个Design Pattern我的看法就一句话,
去TMD。
回复  

使用道具 举报

3#
 楼主| 发表于 26-4-2010 14:28:06 | 只看该作者

怎么理解这一段呢?Dependency Injection

提示: 作者被禁止或删除, 无法发言
定义一个Interface,  IContactManagerRepository
再定义一个使用这个Interface的类,  EntityContactManagerRepository


然后用如下语句调用:
  1.         private IContactManagerRepository _repository;
  2.         
  3.         public ContactController()
  4.             : this(new EntityContactManagerRepository())
  5.         { }

  6.         public ContactController(IContactManagerRepository repository)
  7.         {
  8.             _repository = repository;
  9.         }
复制代码
看起来好复杂啊,只好死记硬背。
回复  

使用道具 举报

4#
发表于 26-4-2010 14:32:42 | 只看该作者
接口,模式应该指上无,心中有,在重构时在成型也不迟
如果你是用Windsor做DI的话,不用接口,方法声明为virtual也是可以的

[ 本帖最后由 Yok 于 26-4-2010 14:35 编辑 ]

评分

参与人数 1威望 +49 收起 理由
xblues + 49 谢谢分享!

查看全部评分

回复  

使用道具 举报

5#
发表于 26-4-2010 14:37:26 | 只看该作者
如果你要用AOP+DI,实际在运行时那个类已经不是你写的类,而是一个遵循你的接口或者继承于你的类的动态代理

评分

参与人数 1威望 +49 收起 理由
xblues + 49 谢谢分享!

查看全部评分

回复  

使用道具 举报

6#
 楼主| 发表于 26-4-2010 15:22:33 | 只看该作者
提示: 作者被禁止或删除, 无法发言
记得大约10年以前,写传统ASP代码和PHP代码都很少用到这些Design Pattern的概念,都是一路写下去。
记得最初使用的设计思想的是Java社区,现在动不动就看到这些,到处都是。

软件设计已经不再是一门简单的民工工作,我这样的民工入门难啊。
回复  

使用道具 举报

7#
发表于 26-4-2010 15:28:30 | 只看该作者
模式也是逐渐演化出来的。
对于以前代码写的不多的人来说上手就直接套模式效果会适得其反的。
只有在有了积累了以后才能逐渐应用和理解模式的精髓。这个过程一般速成不了。
比较高的境界是在一处地方同时应用着几种模式。对入门者来说很难看懂,不过对高手来说,有着共通的优雅和快感。

本人未入门。

评分

参与人数 1威望 +49 收起 理由
xblues + 49 谢谢分享!

查看全部评分

回复  

使用道具 举报

8#
发表于 26-4-2010 15:29:54 | 只看该作者
另外最初的设计应该不是来自java,应该是smalltalk吧。至少也应该是C++。java的语言设计倒是吸收了不少模式的想法。

评分

参与人数 1威望 +17 收起 理由
xblues + 17 谢谢分享!

查看全部评分

回复  

使用道具 举报

9#
发表于 26-4-2010 21:53:54 | 只看该作者
其实只要你的代码是符合面向对象的基本原则的,你的代码里面就几乎必然会带有一个或几个模式。

实际使用的过程里面,多数时候都不是在“应用模式”,而是自然而然地发现你代码里面的设计模式,然后重构代码,使设计模式显性化,让代码更加易读和优雅。   

对设计模式的理解,其实关键还是对面向对象的理解。 这个急不得的,你只能从小处入手,重视自己的代码质量,思考自己的代码是否符合面向对象设计几大原则 ,并且养成重构的习惯。慢慢的,你就发现设计模式自然而然就会出现在你的代码里面了。

当然不懂这些一样可以coding,只是会做得比较累。非面向对象的代码一般相对而言代码质量差,BUG多,修改比较困难。越复杂的程序,这种差别就越明显。

现在我们公司的活,不懂设计模式基本上是没法入手的。

[ 本帖最后由 woodheadz 于 26-4-2010 22:14 编辑 ]

评分

参与人数 1威望 +49 收起 理由
xblues + 49 谢谢分享!

查看全部评分

回复  

使用道具 举报

10#
发表于 26-4-2010 21:57:27 | 只看该作者
提示: 作者被禁止或删除, 无法发言
我个人意见,每个人做自己模块的实现,只要能做出来,用中文写代码我都没意见,只是在大家交互的地方得遵循一下接口和规范,便于大家互相理解以及之后扩充。

评分

参与人数 1威望 +47 收起 理由
xblues + 47 谢谢分享!

查看全部评分

回复  

使用道具 举报

11#
发表于 26-4-2010 22:39:03 | 只看该作者

回复 #9 woodheadz 的帖子

十分不同意,俺最喜欢C,最喜欢的是Linux Kernel,不否认里面用了OO的一些思想
但是这位同学说非OO的语言不能设计复杂的软件,俺是非常不同意的
OO语言写得烂的Bug也超多,关键在于写代码的人的水平,而不在于语言本身
而且可以这么说,很好的软件的Bug也是超级多的

评分

参与人数 1威望 +17 收起 理由
xblues + 17 谢谢分享!

查看全部评分

回复  

使用道具 举报

12#
发表于 26-4-2010 22:52:36 | 只看该作者
woodheadz筒子说的比我到位呵呵。我好像说错了,是面对对象发展和smalltalk有关。这个和模式应该没什么直接关系。
另外他说的意思我觉得是说不符合OO思想的代码比较容易烂,但这不一定是说非OO的语言就是烂的。c是非OO的,但是通过合理的函数指针分配和其他一些方式一样可以达到OO的思想。C++本身就是就是用C实现的。

评分

参与人数 1威望 +21 收起 理由
xblues + 21 谢谢分享!

查看全部评分

回复  

使用道具 举报

13#
发表于 26-4-2010 23:02:51 | 只看该作者
原帖由 valpa 于 26-4-2010 22:39 发表
十分不同意,俺最喜欢C,最喜欢的是Linux Kernel,不否认里面用了OO的一些思想
但是这位同学说非OO的语言不能设计复杂的软件,俺是非常不同意的
OO语言写得烂的Bug也超多,关键在于写代码的人的水平,而不在于语言 ...


楼上理解错我的意思了。 关键不在于OO的语言,而在于OO的思想。 有好的OO思想,甚至用C语言也能写出很不错的带有OO风格的代码来。
“非OO的语言不能设计复杂的软件”这话是你自己说的,和我可没有什么关系。
不过嘛,呵呵,C语言毕竟是太老了些。除非是嵌入式或者基于老系统的开发,不然普通的新系统还在用C开发的确实很少听说。
C语言比新的OO语言的劣势,尤其是生产率的劣势我想不用我说了。

评分

参与人数 1威望 +19 收起 理由
xblues + 19 谢谢分享!

查看全部评分

回复  

使用道具 举报

14#
发表于 26-4-2010 23:10:11 | 只看该作者
原帖由 浮云 于 26-4-2010 22:52 发表
woodheadz筒子说的比我到位呵呵。我好像说错了,是面对对象发展和smalltalk有关。这个和模式应该没什么直接关系。
另外他说的意思我觉得是说不符合OO思想的代码比较容易烂,但这不一定是说非OO的语言就是烂的。c是非 ...


呵呵,好像早期的很多面向对象思想都是来源于用smalltalk的人的哈... 只可惜我到现在都没见过smalltalk长什么样...
回复  

使用道具 举报

15#
发表于 27-4-2010 09:08:28 | 只看该作者
很多。Java应该是最多了。
PHP也有
回复  

使用道具 举报

16#
发表于 27-4-2010 17:59:48 | 只看该作者
代码写得多了,多多少少自然就会有些模式的思想出来咯。为了模式而模式,效果不见得好。

评分

参与人数 1威望 +11 收起 理由
xblues + 11 谢谢分享!

查看全部评分

回复  

使用道具 举报

17#
发表于 27-4-2010 18:11:30 | 只看该作者
我们学校的学究们就抱着四人帮写代码
回复  

使用道具 举报

18#
发表于 28-4-2010 16:48:17 | 只看该作者
重构是无可避免的,但模式是否只能在重构时体现,我觉得就未必了。
我试过由基础uml做起,一步步地形成架构、类图,在架构和类图阶段引入模式,比较顺理成章。
但事实上我们在写系统时,又基本上无可避免地先代码,然后code review,然后refactor。
这算是一种无奈吧。

原帖由 Yok 于 26-4-2010 14:32 发表
接口,模式应该指上无,心中有,在重构时在成型也不迟
如果你是用Windsor做DI的话,不用接口,方法声明为virtual也是可以的

评分

参与人数 1威望 +19 收起 理由
xblues + 19 谢谢分享!

查看全部评分

回复  

使用道具 举报

19#
 楼主| 发表于 28-4-2010 16:50:23 | 只看该作者

回复 #18 key 的帖子

提示: 作者被禁止或删除, 无法发言
一般都这么干的,好像!
回复  

使用道具 举报

20#
发表于 28-4-2010 16:50:44 | 只看该作者
学术上面搞出来的东西都是在实际中有很高需求才研究出来的。
如果你愿意做代码架构,那么这些设计模式绝对绝对很重要。是很多先人思想的结晶。

评分

参与人数 1威望 +17 收起 理由
xblues + 17 谢谢分享!

查看全部评分

回复  

使用道具 举报

21#
发表于 28-4-2010 19:59:15 | 只看该作者
原帖由 key 于 28-4-2010 16:48 发表
我试过由基础uml做起,一步步地形成架构、类图,在架构和类图阶段引入模式,比较顺理成章。
但事实上我们在写系统时,又基本上无可避免地先代码,然后code review,然后refactor。
这算是一种无奈吧, ...


其实我觉得,大可不必把这当成是一种无奈。 就把重构看作是我们每天的例行动作,就像敲击键盘一样,不也挺好吗?
铁匠用锤子来锻造铁器,我们用重构来锻造系统,这些都不过是我们使用的工具而已。
UML拿来做沟通交流的工具就好了,至于开发,模型驱动的方法,我始终认为是在学院派的理想环境下才能行的懂的特例。人性本身就是不完整的,所以在实践中所以怎么可能会有那么顺利的场景让你一步步模型驱动呢?

评分

参与人数 1威望 +49 收起 理由
xblues + 49 谢谢分享!

查看全部评分

回复  

使用道具 举报

22#
发表于 28-4-2010 20:45:11 | 只看该作者
为了用模式而用模式当然不好
我觉得写代码的时候心里要有些OO的原则

比如写个函数
void Fun(int nParam1,int nParam2)

假设共有100处在调用这个函数,但是需求变了,要加一个新参数int nParam3,这就造成100处代码都要改和编译

那么写一个类或结构包含这些参数是一个自然而然的想法。

class CParameter
{
..
}

void Fun(CParam cParam)

这样当然解决了些问题,但还是不够好

比如这个函数是用来登记宠物的信息,宠物可以是不同类型,比如猫,狗,金鱼或蜥蜴等,那么CParameter就要包括太多信息,这本身就违反了设计类的单一责任原则。
而且即使这么做了,代码中必然有庞大的if-else判定或switch分支。

那么写一个接口或一个抽象类,并把它作为参数是一个好办法
class Creature
{
...
}

void Fun(Creature cParam)

class Cat : Creature
{
...
}

调用的时候

Cat  cat = new cat(...);

Fun(cat);

这样的设计就体现OOP的一个重要原则:依赖倒转原则(抽象不应该依赖细节,细节应该依赖于抽象)---简单说就是不要针对实现编程

以上我们没有使用任何具体的设计模式,但我们遵循了这个原则,本身就可以带来诸如松耦合,易维护性,扩展性等等好处。

23种设计模式就是这些原则的体现!

[ 本帖最后由 lavahx 于 28-4-2010 22:15 编辑 ]

评分

参与人数 1威望 +49 收起 理由
xblues + 49 谢谢分享!

查看全部评分

回复  

使用道具 举报

23#
发表于 29-4-2010 11:14:27 | 只看该作者
我不认同你的观点。正如我在上面所说的,refactor是无可避免;但如果design pattern只能应用于refactoring,那也只是一种无奈。

过去一段时间,我构建了若干个重要的程序框架,虽然说不上漂亮,但由设计开始应用好的方法和架构,的确能带来不少好处。
比如有一个网络协议解释框架,当时我想到的只是两三个协议的应用。我拿出其中一个协议,从use cases做起:

use cases -> sequence diagram -> system architecture -> class diagram -> coding -> testing

其中在sequence diagram与system architecture中间开始考虑design pattern的引入,再在class diagram的时间把design pattern精化,
最后形成第一套代码。这样形成的代码在之后的几个月被扩展到两三万行,一直都比较顺利。

原帖由 woodheadz 于 28-4-2010 19:59 发表


其实我觉得,大可不必把这当成是一种无奈。 就把重构看作是我们每天的例行动作,就像敲击键盘一样,不也挺好吗?
铁匠用锤子来锻造铁器,我们用重构来锻造系统,这些都不过是我们使用的工具而已。
UML拿来做沟 ...

评分

参与人数 1威望 +49 收起 理由
xblues + 49 谢谢分享!

查看全部评分

回复  

使用道具 举报

24#
发表于 29-4-2010 11:20:01 | 只看该作者

评分

参与人数 1威望 +49 收起 理由
xblues + 49 你太有才了!

查看全部评分

回复  

使用道具 举报

25#
发表于 29-4-2010 15:09:20 | 只看该作者
那个例子没有很复杂啊,其实没有加多少代码,好处就是每个文件都小,每个类都只要关注一样东西。实际开发一定都会用到类似的东西: http://www.objectmentor.com/reso ... es_and_Patterns.pdf

如果你没有interface给你的Repository而是直接调用数据库,那么你的unit test也要直接访问数据库了。有interface的话,可以在unit test里面mock一个。 毕竟代码需要的是一个行为,并不需要应考具体的类。

加个service是因为程序的逻辑不止保存那么简单,而且你也不想自己的presenter太复杂,presenter只需要知道调用哪个service的方法就可以了。

评分

参与人数 1威望 +49 收起 理由
xblues + 49 你太有才了!

查看全部评分

回复  

使用道具 举报

26#
发表于 29-4-2010 17:16:59 | 只看该作者
我觉得重构是无法避免的。
我认为绝大多数项目或系统,在真正深入进行代码编写工作前,设计者都无法考虑到所有的问题。如果能够预先画个很漂亮的圈子并
遵照此路线百分百完美实现,基本上说明这个系统还是比较简单的。
如果重构是可有可无的,那么快速构建原型进行验证岂不是成了画蛇添足?
原帖由 key 于 28-4-2010 16:48 发表
重构是无可避免的,但模式是否只能在重构时体现,我觉得就未必了。
我试过由基础uml做起,一步步地形成架构、类图,在架构和类图阶段引入模式,比较顺理成章。
但事实上我们在写系统时,又基本上无可避免地先代码, ...

评分

参与人数 1威望 +25 收起 理由
xblues + 25 谢谢分享!

查看全部评分

回复  

使用道具 举报

27#
发表于 29-4-2010 21:23:04 | 只看该作者
很同意你在这里提到unit test这个考虑因素。
其实很多实现上的考虑,如果没有unit test这一环,考虑点会有很大的不同。
我因为要建立testcase而refactor了好多次代码后,终于明白到这个道理。

原帖由 lol 于 29-4-2010 15:09 发表
那个例子没有很复杂啊,其实没有加多少代码,好处就是每个文件都小,每个类都只要关注一样东西。实际开发一定都会用到类似的东西: http://www.objectmentor.com/reso ... es_and_Patterns.pdf

...

评分

参与人数 1威望 +23 收起 理由
xblues + 23 谢谢分享!

查看全部评分

回复  

使用道具 举报

28#
发表于 29-4-2010 21:27:34 | 只看该作者
无可避免不等于完全依赖,
就象人是无可避免地要死的,但自杀就没有必要了,对吧?

从一开始就设计高大全的的系统当然没有必要,
所以才有agile,xp之类的方法。
我比较接受的一个观点是,提取其中具有典型意义的若干个use cases进行设计和实现,
不断回归扩展,最后建立整套系统。


原帖由 ironcool 于 29-4-2010 17:16 发表
我觉得重构是无法避免的。
我认为绝大多数项目或系统,在真正深入进行代码编写工作前,设计者都无法考虑到所有的问题。如果能够预先画个很漂亮的圈子并
遵照此路线百分百完美实现,基本上说明这个系统还是比较简单 ...

评分

参与人数 1威望 +21 收起 理由
xblues + 21 谢谢分享!

查看全部评分

回复  

使用道具 举报

29#
发表于 29-4-2010 23:21:33 | 只看该作者
原帖由 key 于 29-4-2010 21:27 发表
无可避免不等于完全依赖,
就象人是无可避免地要死的,但自杀就没有必要了,对吧?

从一开始就设计高大全的的系统当然没有必要,
所以才有agile,xp之类的方法。
我比较接受的一个观点是,提取其中具有典型意义 ...



把重构和死亡联系起来,我想你是过头了。 我本来还觉得我们对重构的观点都差不多,但现在看起来还是有很大的不同呢
有一个很好的例子,可以说明我们的区别。 就像我们都知道需求的变化不可避免,在这个事实面前,有两种几乎是背道而驰,而又特点鲜明的做法:
1.以CMM等方法为代表的"学院派"(姑且称为)强调对需求的绝对控制。通过流程进行审核,审慎地将需求引入到开发迭代中。
2.以XP为代表的“敏捷派”则强调拥抱变化,整个XP的基础都是建立在“变化”这一个关键字上的,需求的变化将直接推动系统的进化。化被动为主动。

你所理解的refactor,其实是在被逼无奈的情况下,被动的对代码进行修改。也许你也用了重构工具,使用了经典的重构方法,并且还编写的unit test保证重构的结果,但这些都是在没有其它的办法的情况下进行的“亡羊补牢”的措施而已。就像前面例子里的“学院派”,虽然认识到修改不可避免,但还是尽全力避免修改,力图让修改最小化。你对系统的设计,绝大多数(最少你希望是绝大多数)是在前期的设计就通过UML完成了的。
我所理解的refactor,就像编写程序必须要敲入代码,编译一样,是再理所当然不过的编程的必然步骤,而且重构还是编程步骤中我最喜欢的一个(以前是编译, ). 我每天coding的过程其实就是不断的编码,编译,测试,重构再测试。我对系统的设计,是在我的整个coding过程中完成,重构是我两个最重要的设计步骤之一。另一个嘛,其实就是编码了  “代码即设计!”,呵呵。 相对你而言,我就比较”敏捷派“了。  我也经常用UML,但多数时候是和同事讨论时候用的,多数是画在白板上和纸上。 事实上,我目前的工作电脑上连画UML的工具都没有,只有家里的电脑有个UModel。 当然这个也和我的工作性质有关(我们是做产品的公司,不用和客户进行技术交流)。

其实我不想比较那种方法(或者说那种“派”,呵呵)更好,每种都有自己的长处。我自己做过一段时间的外包,在多数的外包的环境下,确实“敏捷”是完全行不通的。但我始终觉得,敏捷方法的效率,系统的质量,成本都有非常明显的优势。只是敏捷对团队中个人的要求要偏高,而重型方法则有可能用管理方法组织起大量的人力来完成项目吧。

[ 本帖最后由 woodheadz 于 29-4-2010 23:58 编辑 ]

评分

参与人数 1威望 +35 收起 理由
xblues + 35 你太有才了!

查看全部评分

回复  

使用道具 举报

30#
发表于 30-4-2010 00:09:33 | 只看该作者
好复杂,好复杂
回复  

使用道具 举报

您需要登录后才可以回帖 登录 | FreeOZ用户注册

本版积分规则

小黑屋|手机版|Archiver|FreeOZ论坛

GMT+10, 30-4-2024 13:13 , Processed in 0.080487 second(s), 70 queries , Gzip On, Redis On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表