重量级问题——对象的设计

skywater 2003-08-08 10:31:07
在作系统设计的时候,碰到这样一个问题:两种实体之间的唯一的差别就在于它们在运行的过程中,有一个状态会不一样,其余的全部一样;而且事实上,为了这个不一样的状态,实体似乎必须为之准备一堆数据成员和操作方法。
以面向对象的设计模式,该如何优雅而高效地抽象并设计出该实体的对象?
欢迎高手讨论。
...全文
74 21 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
liao2001 2003-08-12
  • 打赏
  • 举报
回复
我认为抽象是要考虑的,只不过是看问题的角度问题,楼主提到“物流管理”,再提到“面包”。。。
我认为,产品是物流的关键,产品有成品、半成品、废品等,成品有熟面包、黄油等,半成品有生面包、生黄油(呵呵,有没有生黄油?)等,废品有。。。。。。

楼主在忙设计没时间来结贴吗?我现在在搞开发,还是很多时间上网的,给我1/5就行,呵呵,开个玩笑
skywater 2003-08-12
  • 打赏
  • 举报
回复
我发的这张帖子,只不过是把石头抛出,引出大侠们的和氏宝玉,相互切磋,相互提高。软件工程永远没有一个一成不变的标准,聪明而勤奋的人们,总会发现更好的解决方法。在漫漫的程序人生路上,祝各位事业有成。
小二,结帐!
ZYEIYOU 2003-08-11
  • 打赏
  • 举报
回复
我提供一简单的办法(假设系统框架已设计好)。
1.按需求提取对象
2.先写一个面包类,一个熟面包类,尽可能详细(不用考虑对象抽象)
3.分析两个类的区别,包括接口,变量甚至保护函数。
4.再分析设计抽象所有可以抽象,并考虑类的可扩展性。
5.将相同的部分(变量,函数)用一个基类表示(可虚,可不虚)。
6.将不同的写两个类.
分析设计也需要一个迭代的过程,如果没有把握就按笨办法,实际操作一下。
保证相同的代码保留一份很重要。

如果状态多并可互相转换建议使用GOF的STATE模式。

个人意见,多提意见,不胜感激!
共同学习!!!!!
liao2001 2003-08-11
  • 打赏
  • 举报
回复
大家对这方面的问题好像不大感兴趣,建议楼主把贴子放到〈软件工程〉那边去看看,这边搞设计的人不多,主要是程序员。
liao2001 2003-08-11
  • 打赏
  • 举报
回复
呵呵,如果我是大虾就好了,那样就不用为了生计而发愁了!我只知道些“理论”,现在还是程序员。
面向对象设计我只是学了一点而已,仅仅设计过一个小型接口,那可是我的第一个孩子,有点营养不良。我毕业2年来,3/4的时间在搞面向过程,因为那一次设计喜欢上了面向对象,可在中国面向过程深入“人心”的现实情况下,唉~~~~
我曾建议现在的同事采用面向对象,他说“我觉得面向对象(的程序)运行起来慢了点”,我只好附和“对,是慢了点,不过现在的cpu和内存都很快的”,呵呵~~

家常拉玩,现在我们来谈谈面包问题,以下个人观点:
1\你提到目前项目处于需求分析阶段,如果是这样的话,我建议你先把设计的事“忘掉”,先做好需求先。人人都说面向对象是一个迭代的过程,不要被这个说法误导了,需求做好了,可以大量减少迭代次数。不要把需求和设计过早挂钩,需求不需要设计,设计需要需求。

2\如果开始设计了,我谈谈我的面包问题:
实际问题,就要实际分析了。
生面包和熟面包能不能抽象到面包?他们的共性在哪?派生类应该具有基类的“职责“(也可以说“接口”,注意,面粉只是他们的共有属性)。
显然,面包是食物,可以吃,熟面包就是面包,生面包不能吃,不是面包,只是面团。2个独立的对象。
你疑惑的地方应该是“熟面包和生面包都是面包”,那么也就是说熟面包和生面包能抽象成面包?面包的特性是什么?2者都继承了面包的特性?
简单的说,如果熟面包和生面包没有相同的接口的话,那就是不同的对象;如果有相同的接口,就要看能不能抽象成基类,我认为面包不是他们的基类,因为生面包不能从面包继承而来。

数据库的设计追求的是“非冗余”,这样的话,往往会带来不少的表,对多个表的操作,显然会增加程序的开销,这就有一个折中的问题,存储空间/访问开销=?。我没做过这方面的设计,不好多说,^_^

需求总是会变更的,想一劳永逸,嘿嘿,别抱这种想法,保证“最小改动”才是很现实的目标。
IT-司马青衫 2003-08-10
  • 打赏
  • 举报
回复
回复: PPower(月亮光光,照地堂)
不如采用BCB的面向状态编程思想做就行了
什么事件属性等等
zhaistone 2003-08-10
  • 打赏
  • 举报
回复
能否利用Templete中的部分特殊化设计类,可以显式声明特殊的模板类!
skywater 2003-08-10
  • 打赏
  • 举报
回复
liao2001(知之为知之,不知为不知。。。) 说的极是,我在需求和设计上考虑得不是很充分。不过显然可以看出,liao2001是一个经验丰富、技术高超的大虾,能与你讨论,我觉得非常荣幸。

事实上,我之前主要是从事面向对象的程序设计和开发,做过一些项目,不过,都是在高手的指导下做的。但是很幸运的是,ooa, ood的思维和理念已经深入我心。由于在上一个公司已经没有太大的发挥余地,现在跳槽到一家小公司,作一个比较小型的C/S系统。我的角色是系统分析员,事实上需求分析、系统设计是我负责的。第一次独当一面,困难不小,但也非常的有挑战性。

现在的项目处于需求分析阶段,同时要考虑一些系统上的设计方案。遇到的这个问题,是在物流管理模块。打个比方,就好比面包一样,有的面包进库的时候,就已经是熟的面包,所以它的业务有进库房、保存、出库房等;但是有的面包进库房的时候是生的,当某个时机成熟以后,它会在库房里面变成熟的,此时它就和原先熟的面包完全一样了。从业务需求上来说,这点区别绝对不难理解。但是在作设计的时候,就有一点挠头了。首先是数据库,所有面包的信息都需要保存的,那么我的表怎么设计,才会最高效地满足上述要求。其次,在真正开发的时候,生面包和熟面包如何该设计成为什么样的类。当然,上述问题解决了,网路传输应该也就是水到渠成。所以,我才说了这样的话:“影响的地方有数据库、网络、实现时候的C++类的设计”。不知道作需求的时候,我这样考虑是否欠妥当,请大侠们指点。

当然,我的上司并不是一个很精通技术的人。如果我马虎一点,作一个臃肿而蹩脚的设计,他们挑不出毛病,性能上也绝对满足要求。但是,毕竟是自己的第一个孩子,希望能够做得更好、更精致一点,所以想寻求一种一劳永逸的设计模式,优雅地解决数据存储、编码开发、需求变更、维护升级等后续工作。
hlnpro 2003-08-10
  • 打赏
  • 举报
回复
写错了一点,不好意思阿:

把不同部分抽象为一个抽象类(A),再按照不用的需要继承之(A1,A2)。

相同部分作为一个类(B),其中保留不同部分的基类指针(diff_state)。

大概就是:

class A{
public:
fun1(){}=0;
fun2(){}=0;
};//不同部分的抽象类
class A1:public A{
public:
fun1(){...}
fun2(){...}
};//状态1
class A2:public A{
public:
fun1(){...}
fun2(){...}
};//状态2
class B{
public:
...
protected:
A *diff_state;//状态指针
};//
hlnpro 2003-08-10
  • 打赏
  • 举报
回复
把不同部分抽象为一个抽象类(A),再按照不用的需要继承之(A1,A2)。

相同部分作为一个类(B),其中保留不同部分的基类指针(diff_state)。

大概就是:

class A{
public:
fun1(){}=0;
fun2(){}=0;
};//不同部分的抽象类
class A1{
public:
fun1(){...}
fun2(){...}
};//状态1
class A2{
public:
fun1(){...}
fun2(){...}
};//状态2
class B{
public:
...
protected:
A *diff_state;//状态指针
};//
勉励前行 2003-08-10
  • 打赏
  • 举报
回复
1、两种实体之间的唯一的差别就在于它们在运行的过程中,有一个状态会不一样,其余的全部一样;
  将这种情况归为一个类A。
2、有一个状态会不一样,而且事实上,为了这个不一样的状态,实体似乎必须为之准备一堆数据成员和操作方法。
  这个不一样,另作一个类B,并把类A定义是类B的友元,让A可以操纵B。

这样,类A,B组成一个群体,而且A,B不影响类层次的意义完整性。

如果系统庞大,可这样: 
class A ----- class B
|__________|
|
class C (统一的对外接口)


liao2001 2003-08-09
  • 打赏
  • 举报
回复
昨天没发上去,今天来重写,呵呵,个人观点,仅供讨论!

“说明一点,不仅仅是C++类下的设计,这涉及到整个系统的设计,影响的地方有数据库、网络、实现时候的C++类的设计等,所以说是重量级的呢。”
如果你的出发点是用系统、数据库等等东西来约束面向对象设计的话,我认为你还没开始就已经失败了。面向对象的设计应该是系统无关的,它的约束条件是“强内聚松耦合”,一个对象应该是“独立于”外界的,系统做的仅仅是协调对象之间的交互,从而实现具体功能。

“以面向对象的设计模式,该如何优雅而高效地抽象并设计出该实体的对象?”
在大家大谈面向对象的好处时,往往提到“适合人的思维,适合可观世界”,这也就意味着不同的人看到是的相同的东东。也就是说面向对象设计的好处是,不同的人设计出相同/相近的类,而这些类是以客观世界为依据的,所以我认为不存在“优雅而高效”。

从搂主的意思“两个实体不同状态”,听起来似乎比较简单,往往很多人会想到用一个状态类,如果状态类是一个私有类的话,我觉得还是可取的,不过这也要遵循需求,比如售票员和乘客都是人,用“人+状态”的话,呵呵,我会举双手反对,这时候就应该采用“基类”。

我个人建议是,楼主再多分析下需求,尽量细化需求,我个人感觉你分析的不够。

欢迎大家继续讨论。
skywater 2003-08-08
  • 打赏
  • 举报
回复
说明一点,不仅仅是C++类下的设计,这涉及到整个系统的设计,影响的地方有数据库、网络、实现时候的C++类的设计等,所以说是重量级的呢。
hproof 2003-08-08
  • 打赏
  • 举报
回复
虚基类?
ckacka 2003-08-08
  • 打赏
  • 举报
回复

static(b)
/ \
/ \
(i) (i)
yjh1982 2003-08-08
  • 打赏
  • 举报
回复
把该状态分离出来,成为一个新类,原来的类保留指针,所有操作转由分离后的新类完成
xiaomingyuxiang 2003-08-08
  • 打赏
  • 举报
回复
这应该是一个典型的继承设计,不必强求用设计模式,我的建议是如果只有一个状态的区别,那就设计成共同的抽象基类,不是接口,接口是没有实现的,而抽象基类是有实现的,这样就达到最大程度的重用而可维护性了
hproof 2003-08-08
  • 打赏
  • 举报
回复
如果真的那么“重”,干脆独立出来算了,别老是对象对象的~

就象“内存管理器”与“文件管理器”一样,,分别写一个不就可以了。。
liao2001 2003-08-08
  • 打赏
  • 举报
回复
阿门,我刚才写了一大堆,可是竟然没有发上来,晕!
magic007 2003-08-08
  • 打赏
  • 举报
回复
接口与实现分离
把不易变的部分封装成接口,把易变的部分装配为实现。
--这是我的体会。
状态不一样,可以考虑state模式。
设用state对象来实现状态相关的操作。有多少个状态可用多少个state对象。
加载更多回复(1)

65,186

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧