面向对象,封装变化,可是对象本身就在变化该怎么办呢?

比如说 一个Person类

有地址 address属性
有电话 tel属性
有姓名 name属性

系统呢创建了一个 张三

Person zhangsan = new Person()
...
在系统里跑得挺好

面向对象,封装得都挺到位了。

突然有一天。

他有车了。(需求增加)

咋办呢?

Person类里面没有
car的属性啊

也没有drive的方法啊。

好吧。。。
那咱把这个功能加进去。
新增加了 Driver类继承Person或者Person类里面直接增加了car属性和drive方法....

但是...但是 00不应该封装变化么?如何封装未知的变化呢?或者说 对这种新增需求的变化,有没有比较好的方式呢?

给我感觉 好像这是一种悖论:既要面向对象,又要封装,这好像是永远无法完成的,因为真实世界中的对象总在变嘛。

司机和普通人是有区别的

车主是普通人的类的一个子类
person类不需要动,车主类 继承person即可

通过DCI(桥模式)或者事件实现。

你在家里是儿子,在单位是程序员,人在不同场景上下文扮演不同的角色,不必将所有角色的行为塞入一个人中。

DCI(桥模式)是从结构组合上进行动态变化,根据上下文将角色行为注入到模型中。


[该贴被banq于2013-07-06 07:16修改过]

从业务的角度分析,“人”属于人力资源子系统,“车”属于车辆管理子系统,“人和车”属于售后管理子系统。
从小系统开始设计时,对业务的认识往往是混沌的,设计出的代码自然是强耦合的,所以封装的变化首先不是一个技术问题,而是一个业务认识问题。

我的看法比较质朴,既然情况变了,你的系统就应该跟着变,这合情合理。

面向对象再封装变化,也不是以不变应万变(这是痴心妄想),情况变了(业务约束、业务规则)设计上就变更就行,只要你原有的设计易于扩展就行。

常见的一种分析设计的方式,就是把“本质”的内容和“非本质”的内容分离,把根据情况发生变化可能性比较大的部分模块化或分层的方式分离出来,修改设计和实现只修改这一部分,就很好了。

我认为既然在你这套业务里,车是一件对业务逻辑有意义的东西,就该提前把车设计进去,没有车的人,car = null;而不是等到这个人买车了,才加一个车的属性。

如果车对这个系统无意义,那不管他买不买车,都不需要加这个属性。

另外,如果模型想体现的是这个人拥有的个人财产但不限定类型,那Person里完全可以加一个List<SomeThing>,车是SomeThing的一个子类

@windshome
"面向对象再封装变化,也不是以不变应万变(这是痴心妄想),情况变了(业务约束、业务规则)设计上就变更就行,只要你原有的设计易于扩展就行。"

嗯....深表赞同....目前也只能这样了...我有点想明白....脚本语言的优势了.但现在思路还是不怎么清晰...感觉pyhton要崛起了..

对象之间的关系不仅仅只是继承,继承是强耦合关系,在这里可能不适用,至少可以用最松散的组合关系,如果要加入“Driver”,可以在Person类里根据实际业务需要关联“Role”或“Skill”(一对多),或者“物品”(一对多),car继承物品类。具体取决于系统关注的是人的技能角色还是个人财产,而这个问题通常在系统需求时就可以确定。

为什么一定要在实体类里面去维护那么多关系呢?让你的service去维护

定义是固定的,只有固定的,才能推倒。假设某天没Person了,那你写那些关于Person的方法怎么办?

你的标题提出了一个面向对象的确无法解决的问题,即,
无法封装不可预测的变化,
但是可预测的变化还是可以封装的,
除了楼上的某些哥们说的继承,
还可以新建一个类,将张三那个preson对象放到这个类中,再将car这个对象放的这
个类中,那么这个类中就有 person 和 car 两个东东,你将这个类理解为张三,那么张三就有了个车。。。。

怎么说你这问题呢 ~ 就像一建好的座房子原本高是4米,后面你非得要求这房子的高升级到4.5米。这样的变化并不是拆几面墙就能搞定的,需要把房顶拆了……

2013-08-03 14:23 "@aixs
"的内容
怎么说你这问题呢 ~ 就像一建好的座房子 ...

对象本身变化有两种:结构本身变化和结构的状态变化。

以房子比喻,房子有结构,随着时间推移,在不同时间,这些结构在不同时间有不同的数值,也就是状态。

注意,我们讨论的隐式前提是对象是一种结构代表,对象=结构,之所以,我们能用对象这个词语形容它,因为它本身是一种结构。如果它不是结构,是一种函数,那么就不要用对象思维,而是函数思维。

参考:http://www.jdon.com/45632#23143102

楼主属于面向对象没有入门的,而上面的回复,基本上都没说到点子上。

车,显然不是人这个类的属性,否则,房子,存款,老婆,儿子,等等都可以做人这个类的属性,对吧?

那么怎么做呢?用继承,显然是错的,继承要符合它的特殊限定条件,即便是符合的,你来一个“有车的人”,以后再来一个“有车有房的人”,再来一个“有车有房有老婆的人”这样搞下去,不是很滑稽的么?对吧!

好了,那么如何做呢?你自己开动脑筋想想看。看看能否琢磨出来,先卖个关子。


[该贴被wangcity于2013-08-06 13:28修改过]