转一段CSDN上OO分析的讨论,比起经院式的教材,这段对话要生动的多了。 (100分)

C

cheka

Unregistered / Unconfirmed
GUEST, unregistred user!
注,请留意网友San_Daniel(丹少爷)的帖子,他的设计非常有弹性
主  题:首次使用 OOP 的想思. 希望大家可以引导一下,给个提示就有分哦.....
作  者:igod
所属论坛:C/C++
问题点数:50
回复次数:9
发表时间:2001-8-28 14:48:10



我想用OOP 做一个五子棋的游戏,
不知要怎样的划分类,或要有些什么样的成员函数,
别忘了,给个提示就有分哦...


回复贴子:
回复人: lmh79(阿楚) (2001-8-28 14:54:41) 得0分
我觉得每一个棋子就像人一样,是平等的!
回复人: mhorse(火狮) (2001-8-28 15:17:40) 得0分
1: Class CDrawChessboard: public CDC
负责画棋盘,棋子,以及棋盘,棋子在各种状态下的图案
2:Class CChessBoardStaus: public CDocument
存储当前棋局状态
3:Class CChessAnalyer: public CCmdTarget
根据当前棋局状态及操作者的动作决定下一步走棋(棋法分析器)
回复人: igod(人言可畏) (2001-8-28 17:46:25) 得0分
同道中人.为何不照顾一下呢
回复人: LANDFISH(我要分~~~~~~~~(FAINT)) (2001-8-28 19:27:18) 得0分
我觉得应该把棋子归为一类,作为一个抽象类,负责棋子的移动等。
然后不同类的棋子(如马,象等)作为棋子类的派生类,重载它的
方法(如各类棋子都有自己的移动方法)。.
决策者(即下棋的人)作为一个类,负责下达走棋的指令,做出判断决策等。
系统处理作为一个类,负责图像的重绘,计时,界面等。

回复人: San_Daniel(丹少爷) (2001-8-28 19:52:14) 得0分
这是我前一段写的文档,参考一下吧
3 总论
这个项目的开发目标是一个ActiveX控件,因而整个项目的核心是如何构造一个
符合ActiveX标准的类,使之能够完成需求分析书给定的功能。我们把最终提供
的产品类命名为 GobangGame,由它的名称可以看出,该类描述的是“五子棋游
戏”这一类事物。
现实生活中的经验告诉我们,一场五子棋游戏由以下几个要素构成:
两名游戏者,他们分别执黑、白棋
一名裁判,负责裁定比赛的胜负,以及适时的开始和结束比赛
一套具体规则,供裁判作为判定的依据
一个五子棋盘
两盒棋子
游戏者在游戏中的作用是在棋盘上落子,我们用一个抽象类Player来描述游戏者
的角色,它的主要接口方法如下:
playAStep():在棋盘上下一颗子
setSide():指定游戏者执黑或执白
对于计算机游戏者而言,落子之前要根据棋盘的形势,决定落子位置,然后完
成自己的任务——在棋盘上落子。而对于“真人”游戏者而言,事实上是用户的代
理,他应该按照用户的指示,在棋盘上指定位置处落子。这两类游戏者都兼容游
戏者的接口,并且在具体动作上有所区别,因而我们设计Player的两个子类
Computer和LocalUser,它们对Player有不同的扩展。
Computer
setAILevel():指定人工智能等级
LocalUser
setCommand():命令游戏者在指定位置处落子
至此,我们完成了对游戏者的描述,这时,应当注意到,裁判事实上也是一类特
殊的游戏者,但是他在游戏中所起的作用是判定胜负和控制比赛,有理由使他也成
为Player的一个子类,这时,我们修改Player抽象类的方法playAStep(),赋予它一个更
贴切的名称:act()每一个游戏者在游戏中轮流有act的机会,当裁判act的时候,他将
判断棋局,决定是否宣布某人获胜,或者因为某种原因中止比赛。而游戏者act的时
候可以选择在棋盘上落子或者干点别的。
很容易注意到,在上述抽象分析中,我们给予了五子棋组件最大的灵活性,可以
方便的对Player抽象类派生产生新的游戏者类型。
五子棋盘和棋子我们从简化程序的考虑,将它们合为一体,这套器具我们抽象为
一个抽象类ChessInfo,从这个命名中可以知道,对于棋局状况的记录也由这个类负
责。这样,ChessInfo中就必须包含已经走出的每一步棋,考虑到悔棋的需要,栈结
构是最合适不过的。这个抽象类的接口暂时做以下设计。
redraw():重绘棋盘,包括已经落下的棋子
showMessage(): 显示信息
addAStep():添加一步棋
removeLastStep():移除最后一步棋
clear():清除棋盘,清除对局状态
getPosStatus():查询指定位置的状态,是否落子,落的是哪一方的子
接下来,我们考虑一个智能化的棋具,能够主动的对棋盘形势做出分析,进而对
游戏者提供一定的帮助,比如:重要形势的报警。这样,我们需要增加一个重要的
接口:
analyse():分析棋局,提供参考数据
最后,我们考虑游戏规则,显然一套游戏规则要完成的唯一功能就是判定胜负,
因此我们设计一个抽象类Rule,接口如下:
judge():判定一个棋局,是否有人获胜,以及谁因为什么原因获胜。
getRule():查询一个具体的规则细则。
setRule():设置一个具体的规则细则。
在上述分析过程中,我们得到这样一组类:
Player
Computer
LocalUser
Umpire
ChessInfo
Rule
而最终产品GobangGame将组合上述类对象,这时,注意观察可以发现,上面的类
结构已经超出了“五子棋”的范畴,它事实上可以描述大多数棋类游戏!这些棋类游
戏的的差别只在于规则,于是我们从Rule中派生出GobangRule,并从ChessInfo中派生
出GobangChessInfo,专门用于我们的五子棋。
GobangGame的接口在需求分析书中有详细的描述,在这场游戏中,GobangGame
扮演着联系用户和各类对象之间的桥梁作用,接收用户的输入,对内部对象发出请
求,再将结果反馈给用户,如此周而复始。
接下来,我们讨论这些类横向的关系。
首先,作为一个Player,无论他是电脑或是用户甚至于裁判,他必须知道规则,因
而在Player类中,应该存在一个Rule的引用。同时,他必须了解棋局的状态,所以在
Player类中,还应该有一个ChessInfo的引用。
其次,棋局状态与外部情况无关,不须要知道任何人的存在,所以这是一个相对
单纯的类。
最后,规则要判断一个棋局,必须与该棋局相识,所以对judge的调用应该传递一
个棋局作为参数。
在具体设计中,又注意到一个问题,ChessInfo中包含了绘制的方法,而考虑到最终
产品的移植性,不应该将平台相关的绘制操作与平台无关的分析操作混在一起,因
而引入Bridge(设计模式4.2)模式将两部分分离,设计另一个ChessPainter类族用于实现
具体绘图操作,并被ChessInfo组合,合作完成ChessInfo的设计目标。
以下,描述如何将上述类的对象组合成为一个完整的程序。
我们的最终产品是一个ActiveX控件,因而很自然的想到使用ATL来实现GobangGame类。
可是,由于COM/ActiveX标准是Windows平台上的标准,同时使用ATL会带来很多平台相
关的代码,不利于未来的移植,所以,我们考虑实现一个平台无关的GobangGame类
和一个ATL的GobangGameShell类,两个类的接口大体上一致,用GobangGameShell实现
一些平台相关的代码。并且用户的输入首先被GobangGameShell接收,然后委托
GobangGame完成处理。这样,对于一切支持PUSH式程序的平台,都可以写这样一个
接收消息的Shell,从而保证了GobangGame的纯洁性。
一个GobangGame对象如何与其他对象协同工作呢?首先,GobangGame创建一个棋局
对象(ChessInfo),被所有参与游戏的游戏者共享。接下来创建两名游戏者(Player),用
户对接口属性的控制决定了这两名Player的实际类型(Computer或是LocalUser)。下一步
创建一名特殊的“游戏者”——裁判(Umpire)。最后按照用户对接口属性的控制创建一
套规则(Rule)。游戏者、裁判都应该与棋局对象以及规则相识,这样,整套游戏创
建完毕。
注意,上面没有提到ChessPainter对象的创建过程,因为ChessPainter的子类将是平台
相关的,我们不应该在纯洁的GobangGame中提到它们的名字,因而,在不纯洁的
GobangGameShell中创建ChessPainter对象(与具体的子类相联系)是正确的选择。我们
应该在GobangGame中设置一个setChessPainter()接口,用于接收创建好的ChessPainter对
象,并使用它来初始化ChessInfo。
当所有对象都被创建并正确初始化后,GobangGame要做的事就是接收用户的控制
(包括输入事件和属性、方法调用)。这是一类典型的PUSH程序样式,一组消息处
理函数是必不可少的。大致罗列如下:
onStandardClick() 主键点击,我们把鼠标左键点击事件广义化为这个事件,这样它还
可以描述其他输入条件下的同类事件。
onExtraClick() 附加键点击,我们把鼠标右键点击事件广义化为这个事件。
onRun() 得到运行机会。这个事件应该尽可能频繁的发生,因为每个游戏者只有在
得到运行机会的时候才能完成自己的职责。GobangGameShell可以将它挂在诸如时钟
中断之类的位置上。

回复人: trustme(我爱编程) (2001-8-28 20:47:15) 得0分
楼上的,你可以写本书了
回复人: feeling2000(刘斐) (2001-8-28 21:54:49) 得0分
San_Daniel(丹少爷) ,问个题外话, 你们正规的公司在每做完一个工程(项目)之
后, 所作的技术文档一般主要包括哪几个部分呢? …… 项目目标? 项目内容?
项目实现步骤? 程序注释? 希望你能回答一下。 呵呵。
回复人: kiddycoffee(Kiddy) (2001-8-28 22:14:12) 得0分
gz.
回复人: kiddycoffee(Kiddy) (2001-8-28 22:15:07) 得0分
好东西,先收下了,过一阵子再研究。
 
不错啊
不过换换行好么
 
好看,谢谢啊!:)
 
有学习价值,提意见,请高手出招啦!
 
很精彩,我想现在国内的大部分程序员缺的就是这种分析能力。如果国内程序员的分析能力
提高上以去了,中国软件的整体水平也就相对会提高一个层次。
 
早就想说几句了,但一直上不来
我觉得上面这段话并没有什么特别高明的地方,我不是要贬低作者,只是我觉得这样一段
话并不表明作者水平,实际上任何一个写过稍微复杂一点组件的 Delphi 程序员都可以作
出上面的分析。
从我个人的体会上来讲,一般的应用程序用 Delphi 作 OOD,OOP 真的让人觉得很愉快,
但要对数据库应用程序作 OOD 就不那么容易了,这是由于 Delphi 的所见即所得的设计
方式和数据库编程的模式决定了的,打个比方,一个中学年级成绩统计程序,OOD 该怎
么做,简单的说,年级,班,个人三个对象基本上是可以肯定的,但如何把数据(成绩)
封装到这三个对象中呢?就现在的关系数据库模型来说,要想做到严格的封装,程序量
是相当大的,我想人们一般不用 VC,而用 Delphi 来做就是因为 Delphi 对面向过程
的支持也相当好,你可以部分的面向对象,和数据库的部分还是采用过程化的设计。
要想在数据库应用上实现完全的 OOD &
OOP,我们还有一段路要走,我已经将近一年没
接触数据库应用了,听说 Oracle 的最新版本可以支持面向对象的数据库设计,不知具
体到结合 Delphi OOD 是怎么回事。
一点个人看法,见笑了。
 
补充几句,
我觉得“国内的大部分程序员缺的就是这种分析能力”实在是贬低了我国的程序设计水平,
国内的大部分程序员并不是缺这种分析能力,而是因为项目和条件的局限限制了这种分析
能力的发挥。
 
其他的不敢说 感觉OOX配合UML或者说画XX、XX、XX、XX图更有实效性
 
9494同意楼上
不过xx xx xx xx图画起来太麻烦不过倒是挺明白的看起来
我现在也用xx图作分析,要是有一个工具能自动生成delphi代码就好多了
 
OOP是好,但没必要什么都OOP吧。
杂交水稻的性能要高于纯种水稻。
如果袁隆平欣赏Java的话,那么它的隆平高科也就没戏了,取人之长补己之短
 
的确,只有在软件项目达到一定规模时,OOP才能显示出它的优势。
 
OOP的优势在于明白,易懂。
 
不管怎样, 软件工程对我们来说还是相当的重要
 
说句行外话:xx xx xx xx 图是什么玩意? 怎么画? [8D]
 
听课来了
 
说的好了我就顶。我顶。
 
看完后我还不知从哪里开始入手编码。
相信作者继续深入分析时会遇上很多问题,应该还要深入点才有意义。
个人意见。
 
呵呵,这是仅是理论而已,
说和做是有差距地
谁能按照以上的设计思想 编码实现之,则俺佩服的很![:D]
 

Similar threads

I
回复
0
查看
517
import
I
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
顶部