面向对象设计中的继承、组合、聚合

在c++和java世界里,面向对象设计是老话题,基本上看过一两本书,做过一点开发的人,你问他关于面向对象设计中的继承、组合、聚合,他肯定能回答出来,也会写基类、派生类、java中的接口等等.
但实际情况是不是这样呢在真实的系统开发中,他们设计出来的类层次,真的理解透了面向对象设计吗,特别是继承、组合、聚合之间的区别吗前段时间分析了下以前老员工写的一个模块,这些老员工可是每月8000~9000元的基本工资,年底奖金都是几万,在广州一般国内企业算很高,道理上说这些高级c++程序言不论是编码水平还是设计水平,应该是很合格了吧,应该把类设计的很好,有可扩展性和维护性。实际上呢,让人大跌眼睛,看来实际项目系统中的设计没那么简单。
为什么看书时很多人都很明白,一到实际开发就乱套了。你看看书上的例子,每次不是拿图形来举例,就是拿动物来举例。比如用动物来说明继承关系:
Animal(动物)
|
------------------
| |
Cat(猫) Dog(狗)
大家基本上都能明白,动物是抽象的概念,猫和狗是动物的一种,他们都有年龄、体重这些共同的属性,都有吃东西这个行为, 我们自然知道把这些共同的东西体现在Animal类里. 拿这些很明白的例子来分析,大家都很容易搞清楚三种情况:是一种(继承),有一个(组合),使用了(聚合). 真正的系统开发中,很难区分的清楚,比如我们做移动电信系统,其中就有一个数据同步模块,管理我们的内部系统和移动boss系统之间的数据同步. 数据同步分为开户同步、销户同步等等.
DataSync(基类)
|
--------------------
| |
OrderSync CancelSync
这些数据同步最后采用HTTP+SOAP协议发送给对方,因为SOAP打包是和具体参数以及XML schema定义相关的,是各个子类特有的; 然而对HTTP的打包和发送,这块代码是大家共有的,因此实现的人就把这块代码移动到基类DataSync来实现,然后采用模板方法设计模式来获取不同的HTTP body内容。
看来一切都正常,是个好继承体系. 随着项目发展,现在要添加对某平台的数据同步,但是它不采用HTTP协议来通讯,采用直接在TCP层上跑自己的自定义格式。因为以前把发送那部分代码放到了基类里,现在这部分代码变化了,为了继续使用模板方法设计模式这个已经成型的框架,结果只有修改基类的发送部分代码了。
这个解决方案造成我们引进一个新需求时,需要修改我们的基类!细细分析了<>的第二部分: 面向对象的设计原则,就知道这个设计违反了“开-闭”原则。这个原则说的是,一个软件实体应当对扩展开放,对修改关闭; 在设计一个模块的时候,应当使这个模块可以在不被修改
的前提下被扩展。
为什么会违反这一基本原则呢 原因就是理解错了继承、组合、聚合在这一实际问题上的关系,我们数据同步模块对上层客户模块来说,上层并不关心你采用什么协议发送数据,只管把该给你的数据给你提供完备; 从数据同步模块本身来说,它的部分子类是采用了HTTP协议来发送数据,将来
的一些新加进来的子类,可能采用其它协议来发送数据,所以这里是一种聚合的关系。
如果早期我们就正确发现这一关系,把HTTP打包发送做成一个工具类,子类仅仅通过聚合的方式来引用它,基类并不写死这块代码,那么我们现在新加入对某平台的数据同步,并不会造成修改基类的现象,只是把新功能添加进去而已,这不就满足了对扩展开放、对修改关闭的“开-闭”原则吗。
从这一实际现象看出,很多人虽然拿着高薪,做着公司的高级程序员,其实并不都是很好理解了面向对象设计的各个方面要点。为什么他们还是很厉害,拿高薪呢一个是他们是老员工,对业务十分熟悉,掌握着公司的业务和技术秘密, 不管设计的如何垃圾,他们总能把功能实现出来; 第二
就是老板根本就不看代码,也看不懂代码,只管最后功能实现就是了,他根本无法理解这种设计错误造成的软件可扩展性、可维护性、可复用性的问题,增加了工作量,以为全部是业务逻辑复杂性造成的。
关于面向对象的设计原则:“开-闭”原则、里氏代换原则、依赖倒转原则、接口隔离原则、组合/聚合复用原则、迪米特法则, 请细细阅读java与模式》第二部分,不管是c++程序员还是java程序员. 理解了这一部分,才能把握全书,才能理解设计模式解决了什么,这是《设计模式》那本书
没有提到的关键点!
现在很多C++程序员,依然写着带类的C程序,C++因为兼容C,造成了拥有4种设计并存:结构化设计、基于对象设计、面向对象设计、泛型设计。在这么复杂的环境里,偏偏这些程序员不学习,很少看c++之父的《c++程序设计语言》、著名的《C++ primer》、经典的《Effective C++》和姊妹篇《More Effective C++》、四巨头《设计模式》等等关于设计和编程的经典著作。 而java程序员呢,常常发现没看过《java编程思想》、《java与模式》、《重构》、《深入java虚拟机》等等,就知道摆弄structs/hibernate/spring/jboss/weblogic这些框架,还不一定很好理解其架构体系了,搞不清楚类动态装载机制和反射机制以及动态代理等等。
程序员分两种:一种是天才式的人物,不用学习就能在设计和实现上做的完美无缺; 另一种就是智力平常的普通人,是需要通过读书学习、项目经验、同事朋友间交流沟通来提高技术的。我自己是后一种人,所以不断的学习C++/java方面的东西,和其它同事沟通。你是那一种人呢难道你是天才,是天才请告诉我,我向你请教以便快速提高。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值