浪迹福州

学习.net有一段时间,目前仍在学习中

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  7 随笔 :: 0 文章 :: 88 评论 :: 0 引用

    java和c#通常被认为是完全面向对象的语言,所有基本代码必须写在某个类中。但是,很多java和c#程序员编写的代码并不是真正面向对象的。有这种事?确实有,面向对象的编程语言只是提供了封装、继承和多态的机制,并不能保证我们用它写出的程序是面向对象的,即使我们把“人”和“狗”的代码糅合在一起,也不会导致编译和运行出错,我们来看一个c#编写的“人与狗的故事”:     

 

Code

 

    这段代码包含两个类Program和Story,单纯从语言层面讲,是面向对象的。但Story中把故事、狗和多个人等的代码糅合在一起(如果故事情节涉及板砖和商店的细节,还会更乱,而且不仅用到人的名字,还有年龄穿着等,故事有时间地点等等,为例子简单,没有提及),称为面向对象的设计,完全说不过去。

    如果需求不发生变化,这段代码不会有太大问题,没必要把类分的那么清楚。但需求还是变了,要求增加一个故事二:狗主人在另一天出门时遇到了朋友B,给B讲述了发生在前几天的故事一,并且讲述中他添油去醋,并没有按故事一的实际情节讲,我们来看代码:

 

Code

 

    这时代码已经变得无法忍受了,如果需求再变,不堪设想。也许有的朋友要说,需求不至于一直变吧,我想说:需求不变才不正常,因为需求是人类思想的反映,人的想法是不断变化的,整个世界也在变化。高楼大厦之所以没有经常拆了重建,并不是人们对它满意,而是反复拆建需要大量时间和金钱。而软件相对于建筑来说,只有设计过程(写文档和编码都是设计),没有建造过程,真正的建造过程是在代码写完后由计算机瞬间完成(编译成二进制exe、dll),所以人们只要不满意就可能让它“重建”。可以设想一下,假如代码完成后要由人工打纸带(像最初的程序,0打孔,1不打)来编译,或许随便找一个B/S程序够一个人打几年的,这时需求还是会变,但不会要求程序员去修改了——将就着用吧,不然就洗洗睡先。

    认同了需求是变化的,就要找办法解决问题,面向对象相对于面向过程的主要优势之一就在应对变化上,可能也是面向对象在系统软件开发方面流行的主要原因。上述代码有些过于初级,有一定经验的程序员可能会把代码写成这样: 

     Story有发生时间、地点等属性和GetStory方法,Person有被咬(被咬后的反映)和打狗等方法,如果故事情节涉及Brick(板砖)和Shop(商店)的细节,还会有这两个类,这样基本有了貌似单一职责的几个类。其实,这仅仅是对代码的“归类”,没有做到单一职责,比如Person中的BefallBite(被狗咬)方法会遇到这样的问题:

    如果Person实例是小孩,反映可能是坐在地上大哭

    如果是大人,可能是找板砖

    如果是狗主人家的小孩,狗可能只是轻咬他玩得,不会哭,会跟狗一起玩

    如果是大人,又是狗主人被咬,不一定舍得板砖拍……

    ……

    显然,Person还应该有一些子类:

    这样就基本有了职责单一的类结构。但我们还是发现了问题,Person的子类比较多,如果再加上“根据被狗咬的部位不同反映不同”(Baby被咬屁股不会坐地上哭,可能是趴着哭;大人被咬右手可能无法拿板砖),那么子类将会更多。这时仅仅靠最基本的单一职责原则及其它几条原则已经不能做出良好的面向对象设计,设计模式就是在面向对象的基础上进一步提高软件应对变化能力的“良药”。本例是典型的桥接模式应用场景,笔者将在后续博文中用更复杂更完整的例子和大家共同学习设计模式的综合运用。

 

PS 1:

    本文提到的三种编码方式应该可以代表三种编码阶段,在结尾提到了设计模式,其实在知道用设计模式后还有三个阶段,纯属个人看法:

    1、在单一职责等基本原则做的不太好时就接触了设计模式,根据各种模式定义的场景大量运用。这种阶段去做大项目,遇到的问题往往比最初级的混合编码阶段还多。

    2、基本功底打得扎实后,逐步学习运用设计模式,遇到问题能够根据设计模式定义进行思索,合理解决问题

    3、设计模式的定义经常不记得,设计和编码时只根据基本原则进行,遇到问题就重构代码,重构后发现好像和某种模式定义的场景类似,查书后确定是一样的……

   

    呵呵,设计模式最好不要强求,自然形成就好。

 

PS 2:

    刚开始写博客,对编辑器不熟悉,我贴的代码好好的,发布后对齐格式有点乱,反复几次搞不定;还有贴个类图要先截图存gif,再传上来,很麻烦。请高手留言指点,多谢!我用的编辑器是 TinyMCE(推荐)

posted on 2008-09-27 10:55 浪迹福州 阅读(2072) 评论(22)  编辑 收藏 网摘 所属分类: 2、面向对象软件设计6、源码片断

评论

#1楼 2008-09-27 11:05 chegan      
好文,例子代码有点长,呵呵
  回复  引用  查看    

#2楼 2008-09-27 11:23 金鱼      
LZ,写的不错。希望有更多好的文章陆续出炉!

  回复  引用  查看    

#3楼 2008-09-27 11:26 念时      
写得不错 期待后面的文章ing……
  回复  引用  查看    

#4楼 2008-09-27 11:31 Mars1986      
最后例子的代码发布一下,
学习ing。。。

  回复  引用  查看    

#5楼 2008-09-27 11:43 子逸      
不错, 顶一下
  回复  引用  查看    

#6楼 2008-09-27 11:58 麦子无穗      
个人建议故事做成抽象类比接口好,里面的GetStory为抽象方法。接口更偏重一个共有的行为。比如人和狗都可以有呼吸接口,咬人接口。故事是一个总的抽象,每个故事都必须有的时间,地点,人物。至于怎么组织,由每个具体故事类来实现(即GetStory抽象方法)。这样做的好处是比如故事要加一个背景的属性,如果你用接口,你所有实现接口的类都要去改,而用抽象类就只需要改抽象类就好了:)

有点钻牛角尖了。嘿嘿。

  回复  引用  查看    

#7楼 2008-09-27 12:01 麦子无穗      
狗少主人这个属性。嘿嘿:)
  回复  引用  查看    

#8楼[楼主] 2008-09-27 12:11 浪迹福州      
非常感谢大家的回复!

关于抽象类和接口的区别运用可以看我的另一篇文章

http://www.cnblogs.com/zhangql/archive/2008/09/26/1299615.html" target="_new">http://www.cnblogs.com/zhangql/archive/2008/09/26/1299615.html



IStory的确改成抽象类更好,呵呵。几个类的关联关系也没有画上去

本篇仅仅是让大家建立起面向对象分析解决问题的概念,所以没有考虑太细,最后的类图也没写成代码,真的去写人与狗的故事太无聊了吧(:

IStory的图片就不改了



后续文章会有一个五子棋的完整分析过程和代码,综合运用了多种设计模式,重点是纯属重构得来,不是刻意运用。还会包括人工神经网络算法的简单应用,请大家关注!

  回复  引用  查看    

#9楼 2008-09-27 13:39 Roger ZHAO      
@浪迹福州
博主是牛人,静等您的后续文章。

  回复  引用  查看    

#10楼 2008-09-27 14:35 雪涛      
good
  回复  引用  查看    

#11楼 2008-09-27 14:43 xiao_p      
下一步 将 person 的 BefallBite 做成一个 接口IBite的 多态体系。

然后 person 保留 一个 IBite的 引用 ,
就成 strategy 了!!!

  回复  引用  查看    

#12楼 2008-09-27 14:49 xiao_p      
其实 这样的 设计 在真正的 开发中 未必就又什么好处
又的时候 可能还会带来 很多负面影响,也就是设计过度!

所以,设计的时候,不断的重构还是很又必要的。

另外就是 ,如果c#支持方法多态,而不是实例多态,可能这个问题就又更优美的解决办法了。。。

  回复  引用  查看    

#13楼[楼主] 2008-09-27 14:56 浪迹福州      
@xiao_p
方法多态指的是委托么?观察者模式我倾向于用事件实现,而不是接口,事件可以仅让某个方法变得灵活,比接口耦合度更低一些吧

  回复  引用  查看    

#14楼 2008-09-27 14:56 麦穗      
@xiao_p
同意,但是也同意楼主说的,设计模式不要强求,自然就好。我在加一句,适合项目变化就好:)

期待下文哟

  回复  引用  查看    

#15楼 2008-09-27 14:58 麦穗      
@浪迹福州
弱弱的问一句,观察者模式中用接口实现的?我一接触的时候就是用事件呀?

  回复  引用  查看    

#16楼[楼主] 2008-09-27 15:06 浪迹福州      
@麦穗
可以,不过c#程序员可能更喜欢用事件实现
适配器模式也分类适配和对象适配,不能因为类适配用的少就摸掉吧,接口实现观察者模式也是这个道理

  回复  引用  查看    

#17楼 2008-09-27 16:58 闫帅豪      
写得不错 期待后面的文章ing……

  回复  引用  查看    

#18楼 2008-09-27 20:49 canbeing      
昨天才看了博主的一编好文,今天又有一篇,兴奋不已,期待更多~~
  回复  引用  查看    

#19楼[楼主] 2008-09-28 10:53 浪迹福州      
@xiao_p

http://www.cnblogs.com/zhangql/archive/2008/09/28/1301247.html" target="_new">http://www.cnblogs.com/zhangql/archive/2008/09/28/1301247.html

新的一篇博文中,我对比了委托和接口的使用,欢迎参与讨论

  回复  引用  查看    

#20楼 2008-09-28 11:04 浪尘      
你好,你的博文被http://www.c-sharp.cn C#中国技术论坛收录

URL:http://www.c-sharp.cn/viewthread.php?tid=65&extra=page%3D1&frombbs=1" target="_new">http://www.c-sharp.cn/viewthread.php?tid=65&extra=page%3D1&frombbs=1



如有版权问题请联系我,希望能常交流!

  回复  引用  查看    

#21楼[楼主] 2008-09-28 13:07 浪迹福州      
@浪尘
多谢帮忙转载,常来踩踩
不过能否把原文的链接地址加上

  回复  引用  查看    

#22楼 2008-09-28 16:19 Doho      
期待下文
  回复  引用  查看    

发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 1299828




相关文章:

相关链接: