VC面向对象开发分析与设计实例解析

  • 来源: 互联网 作者: rocket   2008-03-18/11:48
  • 众所周知,面向对象的程序设计更适合对现实生活中的描述,更加体现了软件的工业化的精神,所以现在大部分的软件开发工作都围绕OOP的思想来进行的。但是在对现实生活中的实际问题,如何对所研究的系统进行面向对象的分析与设计呢?本篇文章以一个实际的例子,向大家介绍一下如何对实际问题进行分析和设计。

    一.问题描述:

    该实例是一个电梯载客问题,问题的描述如下:
    某贸易中心共10层,设有载客电梯1部。为了处理问题的方便,有以下的限定条件:
    (1) 电梯的运行规则是:可到达每层。
    (2) 每部电梯的最大乘员量均为K人(K值可以根据仿真情况在10~20人之间确定)。
    (3) 仿真开始时,电梯随机地处于其符合运行规则的任意一层,为空梯。
    (4) 仿真开始后,有N人(>20人)在该国际贸易中心的1层,开始乘梯活动。
    (5) 每个人初次所要到达的楼层是随机的,开始在底层等待电梯到来。
    (6) 每个人乘坐电梯到达指定楼层后,再随机地去往另一楼层,依此类推,当每人乘坐过L次(L值可以根据仿真情况在3~10次之间确定)电梯后,第L+1次为下至底层并结束乘梯行为。到所有人结束乘梯行为时,本次仿真结束。
    (7) 电梯运行速度为S秒/层(S值可以根据仿真情况在1~5之间确定),每人上下时间为T秒(T值可以根据仿真情况在2~10之间确定)。
    (8) 电梯运行的方向由先发出请求者决定,不允许后发出请求者改变电梯的当前运行方向,除非是未被请求的空梯。
    最后开发的软件要求:
    (1) 设计一个易于理解的界面,动态显示各梯的载客与运行情况(上、下或停止),动态显示各楼层的人员停留情况与要求乘梯情况;动态显示从仿真开始到目前的时间。
    (2) 可变动的参数(K、N、M、L、S、T)应在程序开始时从对话框输入。

    二.系统分析与设计:

    采用OOP分析的关键就是要对问题的对象空间的分类(类的分析与设计,这一点跟面向过程的流程图设计不太一样),也就是在整个系统中包括那几个类,每个类包含那些属性特征和行为特征。对于上面的电梯问题,很明显有两个类:即电梯类和乘客类(从所设计到的对象描述可以观察到,但是有的问题即使这一步也要仔细分析)。电梯类应该反映所有关于电梯状态和行为的信息,而乘客类也应该反映这些信息。综合上面问题的表述,现在将分析结果整理如下:
    乘客类:
    Cpassenger
    {
    bool bInLift; //是否在电梯里
    bool bSignal; //发出请求标志
    bool bStart; //仿真启动标志(false标志仿真结束)
    Cstring flag; //标识每个人得序号以及需求层数
    Int iAtFloor; //所在楼层
    Int iToFloor; //要去得楼层
    Int iLifts; //已经乘坐电梯得次数了
    Int number; //乘客得序号
    }
    电梯类:
    Celevator
    {
    bool bStart; //仿真开始标志
    int iAtFloor; //当前所处得层数得起点
    int iToFloor; //即将去得层数
    int iPassengers; //电梯里得人数
    bool bStop; //电梯停止标志
    bool bIsEmptyOperation; //电梯是否空载运行
    CArray<CPassenger,CPassenger&> m_passengers; //存放载处于电梯里面得乘客
    }
    这里说明一下,CArray<CPassenger,CPassenger&>是MFC里面的一个模板集合类,第一个参数表示该集合所存储的类别,第二个参数表示对该集合里面的元素所采取的访问方式,这里采用的是引用的访问方式,这种方式通过传递32位指针来进行访问,它同时兼有地址访问(效率高)和值传递的双重优势,现在一般对大的对象的存取一般提倡使用这种方式。
    另外,这里也引用了view类,定义如下:
    class CLiftsimulationView : public CFormView
    {
    UINT m_nTimer;
    int k;
    int n;
    int l;
    int s;
    int t;
    int floor;
    CPassenger m_passenger[100]; //最大为100个乘客
    CElevator m_elevator; //一个电梯
    int iSrcFloor,iDesFloor; //分别代表载客时得起始楼层和终结楼层,用在ontimer中
    int iEmptySrcFloor,iEmptyDesFloor; //分别代表空载时得起始楼层和终结楼层,用在ontimer中
    int itimes[41];
    DWORD ElapseTime;
    void DeleteColor(int src);
    void DrawColor(int src,int increment);
    };
    这里大致把各个对象的成员设定出来了,为了方便存储,将所有的变量定义为public的类型,这样可以提高存储的效率,当然了,它也破坏了OOP封装的思想,降低了对象与对象之间的隔离性。这里因为问题不是很复杂,所以我们采用前面的方法。至此,类设计基本结束了,当然了,很多时候不是一开始就可以把类设计得很好,往往都是要先设计一部分,然后在后面得问题得处理中,还要对原来设计的类结构进行添加和删除工作的。这里要特别注意的是类设计的最终目的是降低系统的耦合,达到程序逻辑与数据之间的分离,更有利于代码的编制和维护。


    三.代码编制:

    前面已经完成了类设计,那么剩下来的就是应该是系统逻辑部分的实现了,对于系统整体来说,应该有一个事件侦测体系,用来对系统每个乘客和电梯的状态的侦测,以便发送或者修改必要的信息,该侦测体系的周期定为1秒钟(可以用定时器实现),然后用串行的方式来模拟并行的。如果把思路总结一下,应该是跟动画片的原理是一样的:将多个固定和静止的画面定时、按顺序地放映出来,就变成了活动的画面。所以,可以在程序中定义一个主循环,在该循环外进行必要的初始化,进入后每秒钟执行一次,以遍历方式一一激励当前已经产生的对象,由它们根据自己的当前状态和相关的状态变化规则,决定是否需要改变、改变成什么样的状态,以及按照上述行为特征的设计展示必要的对象状态。
    根据上面叙述的思想,下面列举主要列出"事件侦测体系"的代码:
    (应该在另外一个函数来触发次函数,即调用SetTimer(1,1000,NULL)即可)
    void CLiftsimulationView::OnTimer(UINT nIDEvent) //主要在这里处理所有得逻辑
    { int i=1;
    int j=1;
    int a;
    int flag1=0;
    CString str1,str2;
    CString showtime,sen,m,h;
    DWORD dwTime;
    if (nIDEvent==1) //整个系统来驱动,这个是最小得时间单位
    {if (this->m_elevator.bStart =true) //电梯在仿真
    { //对所有乘客循环查询,类似于消息循环,这是电梯核心程序得入口
    for(i=1;i<=this->n;i++)
    {if (this->m_passenger[i].bInLift ==false && this->m_passenger[i].bStart ==true && this->m_elevator.bStop==true && this->m_elevator.bIsEmptyOperation==true)

     


    评论 {{userinfo.comments}}

    {{money}}

    {{question.question}}

    A {{question.A}}
    B {{question.B}}
    C {{question.C}}
    D {{question.D}}
    提交

    驱动号 更多