发现对象及其属性、行为定义面向对象的简单设计方法及示例1怎样发现对象2定义属性3确定行为4C++编程发现对象及其属性、行为定义1怎样发现对象我们在这里谈发现对象,是基于面向对象的基础之上的。重点是在面向对象程序设计中如何去识别对象。在面向对象程序设计中,问题域和系统责任是发现对象的出发点。二者从不同的角度告诉分析员应该设立哪些对象。前者侧重于客观存在的事物与系统中对象的映射;后者侧重于系统责任范围内的每一个职责都应落实到某些对象来完成。发现对象及其属性、行为定义1.1从问题领域发现对象从问题域中去发现对象,例如问题域是物资采购,我们在分析发现对象时,就应从人员、物品、设备、事件、表格、结构等因素去考虑。●人员:大多数系统的问题域都涉及各种各样的人员,需要考虑的是以下两种情况:一是需要由系统保存和管理其信息的人员,如供货商;二是在系统中扮演一定角色(提供某些服务)的人员。符合上述情况之一者,应考虑用相应的人员来描述。发现对象及其属性、行为定义●组织:在系统中发挥一定作用的机构。●物品:需要系统管理的各种物品。除了各种有形的,还要注意那些无形的事物。正因为它们是无形的,容易被忽视,所以要特别注意。●设备:在系统中动态地进行,由系统进行监控或者供系统使用的各种设备。仪表、机器等这些对象也可以广义地属于物品的范畴,不过这里强调的是它们的动态特征。为了使分析模型不受硬件选择的影响,计算机设备已经被屏蔽起来,不需要在被开发的系统中设立相应的对象。发现对象及其属性、行为定义●事件:指那些需要由系统长期记忆的事件。大部分系统每时每刻都可能会发生许多事件,其中有些事件的信息需要在系统中长期记忆。对于这样的事件,可考虑设立相应的对象来记录其信息。我们首先要判断哪些事件是需要长期记忆的,然后根据其信息的复杂程度及其与其他对象的相关情况决定是否为它设立一个对象。发现对象及其属性、行为定义●结构:通过考虑结构可以得到一种启发——从已经发现的对象联想到其他更多的对象。例如,考虑“汽车”这个对象的类在一般-特殊结构中的位置,向上可以联想到“车辆”,向下可以联想到“客车”和“货车”,左右可以联想到“摩托车”;考虑它在整体-部分中的位置,可以联想到“车队”和“发动机”。发现对象及其属性、行为定义1.2从系统责任发现对象通过对问题领域的考虑,发现了许多对象,但是可能还存在一些疏漏。通过考虑系统的责任可以检查所存在的疏漏,发现遗漏的对象。可能无法从问题领域中找到相应的对象来提供系统责任所要求的某些功能(例如系统安装、配置、数据信息备份等),这说明我们遗漏了对象,此时就必须按照系统责任所要求的每一项功能,查看是否有相应的对象来实现,如果没有就可以考虑增加一些对象来实现这些功能。发现对象及其属性、行为定义系统责任要求的某些功能可能与实现环境有关。OOA的对象不提供这些功能也是正常的,这就应该推迟到设计阶段考虑。因为按照我们的原则,OOA模型应该独立于具体的实现环境。发现对象及其属性、行为定义1.3对象的审查和筛选按上面介绍的方法我们可能会找到许多候选对象,这些对象中可能有一些是重复的,也可能存在一些对OOA模型无用的对象,这就要求我们对已找出的对象进行逐一审查,丢弃那些无用的对象,然后精简、合并一些对象,并区分哪些对象是应该推迟到OOD阶段考虑的。1.舍弃无用的对象对于每个候选的对象,要判断它在系统中是否真正有用,判断的标准是它们是否提供了有用的属性和服务。发现对象及其属性、行为定义(1)通过属性判断:这个对象是否将记录一些对用户或者对系统的其他对象有用的信息?也就是说对于这个对象所对应的事物,是否确实有些信息需要在系统中进行保存和管理的?如果回答是肯定的,则这个对象是有用的。(2)通过服务判断:这个对象是否将提供一些对用户或系统中其他对象有用的服务?是否直接或间接地提供了一些用户需要的功能?也就是这个对象所对应的事物,是否有某些行为需要在系统中模拟,并在系统中发挥一份作用?如果回答是肯定的,则这个对象是有用的。发现对象及其属性、行为定义2.对象的精简如果系统中对象的种类及数量过多,则将增加系统的复杂性,应该考虑是否能精简对象。下述情况需要特别注意:(1)只有一个属性的对象。如果对象只有一个属性,应考虑它是被哪些对象引用的,是否能合并到这些对象中。例如,教学管理系统中有“班主任”对象,它只有一个“姓名”属性,而这个对象是被“班级”对象引用的,此时完全可以把它合并到“班级”对象中,只在“班级”对象中增加一个属性“班主任姓名”。发现对象及其属性、行为定义(2)只有一个服务的对象。如果一个对象只有一个服务,没有属性,并且系统中只有一个类的对象请求这个服务,可以考虑将这个服务合并到它的请求对象中。例如,“格式转换器”对象只有一个“文件格式转换”服务,系统中有“输出设备”类的对象使用这个服务,此时把可它合并到“输出设备”对象中,把“文件格式转换”服务作为合并之后的对象的服务。发现对象及其属性、行为定义(3)推迟到OOD考虑的对象。候选对象中那些与具体的实现条件密切相关的对象,如图形用户界面(GUI)系统、数据管理系统、硬件及操作系统有关的对象应该推迟到OOD阶段考虑,不要在OOA模型中建立这些对象,这样可使OOA模型独立于具体的实现环境而只与问题域有关。上面已经为大家介绍了发现对象的方法,下面用具体的例子实现上述方法。发现对象及其属性、行为定义例1超级市场销售管理系统。本系统是超级市场业务管理系统的一个子系统。为了讨论的简练,对其功能做适当的限制:只负责前台的销售管理,而且不处理信用卡付款和会员优惠等业务。其功能需求如下:●为顾客选购的商品计价、收费、打印清单;●记录每一种商品的编号、单价以及现有数量;●帮助供货员发现哪些商品将要脱销,以及时补充货源;●随时按上级系统的要求报告当前款货数量、增减商品种类或修改商品定价;●交接时结算货款数目,报告上级系统。发现对象及其属性、行为定义对这个系统而言,与系统进行交互的活动者有收款员、供货员和它的上级系统。由此我们会发现如下一些对象:收款机:该对象直接与收款员进行交互,模拟收款员的登录、售货和结算等行为。售货员:此类对象用来与实际的供货员进行交互(提醒他们及时补充货物)并模拟他们的行为(在增加货物时修改系统中货物的数量)。上级系统接口:用来处理与上级系统的交互。发现对象及其属性、行为定义考虑到该系统问题域内部的事物和系统责任可以发现如下对象:商品:这是系统中最显著的对象,每一个对象的实例表示一种具体的商品,记录该商品的名称、价格、数量等信息,并通过相应的服务动态地保持这些信息的准确性。销售事件:顾客购买商品时,只要通过一次计价收款就能完成所有的购买,每一次这样的事件都需要在系统中保存一段时间,以便在汇成账目时进行必要的复查,因此要建立“销售事件对象”。发现对象及其属性、行为定义账册:记录一个收款员在一个班次内经手的所有销售事件的款、货账目,负责向上级系统报账,并在交接班时进行账目交接。它的一个对象实例只针对一个收款员的一个班次,不是总账(总账在上级系统中)。按照常识,我们可能会觉得超级市场的管理人员,例如“经理”和“保安人员”也是系统的对象,但是我们会发现这两个对象对本系统来说是不需要的,因此我们可以删除这些对系统来说无用的对象。发现对象及其属性、行为定义在学完上面的内容后,大多数读者大概已经掌握了发现对象的方法。有的读者可能会问这些对象的类是如何建立的,读完下面的例子大家也许就会明白了。在学校学生学籍管理系统中有一个很明显的对象,即学生对象。从问题域分析,要管理在校学生的学籍,必须知道该生的学号、姓名、性别、家庭住址、电话号码、学生成绩等。由于每个学生对象均具有以上的属性,因此在管理时如果我们为每个属性都建立一个备份,会带来大量的重复工作。为了减少不必要的重复工作,我们可以建立一个学生类,并将其封装起来。在声明一个学生对象时,我们只需要将该对象初始化即可,这样就减少了系统开发时的代码。下面是实现该封装的C++代码。发现对象及其属性、行为定义#includeiostream.hclassStudent{protected:charStudentID[20];charName[20];charSex[10];charAddress[20];charTeleNum[10];floatResult;发现对象及其属性、行为定义public:floatAverage(intn);Student(char*pStudentID,char*pName,char*pSex,char*pAddress,char*pTeleNum){coutConstructingthestudentpStudentIDpNamepSexpadrespTeleNumendl;strcpy(StudentID,pStudentID);strcpy(Name,pName);strcpy(Sex,pSex);strcpy(Address,pAddress);strcpy(TeleNum,pTeleNum);}}发现对象及其属性、行为定义在本例中,我们定义了一个Student类,并将Student这个对象封装起来。当一个新生入校时,只要定义一个学生对象,并输入该生相应的信息,就能初始化这个学生,而不需要再重新声明重复的函数,这样就避免了重复的工作,减少了工作量和代码。下面假设有一位家住北京朝阳和平街32号、家里电话号码是010-62394823、名为张三、学号是51000321的男生,当他进入某学校时,该学校只要用Student类定义一个Student对象,并用以上信息初始化该对象即可。这样就充分利用了对象封装的特性。下面的程序段就是用来实现定义该学生对象,并初始化该对象的。发现对象及其属性、行为定义Students(51000321,张三,男,北京朝阳和平街32号,010-62394823)定义并初始化该对象后,就能使用该对象的信息,并且能使用该对象的成员函数。当要求该学生一个学期的平均成绩时,只需要调用其成员函数Average()即可,而不需要再为求该生的平均成绩另写一段代码。在这里,对象封装的优点得到了充分体现。建立对象的目的之一就是为了使用对象所具有的独特的性质——封装和继承。在发现对象后下一步的工作是什么呢?很显然我们发现并建立对象就是要利用对象,在使用对象时,我们必须要弄明白该对象有什么属性,会进行什么样的行为。下面将介绍如何定义对象的属性和行为。发现对象及其属性、行为定义2定义属性为了发现对象的属性,首先应考虑借鉴以往的OOA结果,看看相同或类似的问题域是否有已开发的OOA模型,并尽可能用其中同类对象的属性定义。然后,主要的工作是研究当前的问题域和系统责任,针对本系统应该设置的每一个类对象,按照问题域的实际情况,以系统责任为目标进行正确的抽象,从而找出每一类对象应有的属性。发现对象及其属性、行为定义2.1发现对象的属性从不同的角度去考虑对象,我们会发现其具有不同的属性。因此,我们可以从各种不同的角度去发现对象的属性。2.2按一般常识确定属性对象的某些属性往往是很直观的,按照一般常识就可以知道它应该由哪些属性来描述。例如,人的姓名、职业、地址、电话号码等属性,按一般常识就很容易想到。但要注意,按照一般常识发现的属性有时未必真正有用,应该在审查时去掉那些无用的属性。发现对象及其属性、行为定义2.3本问题领域中的属性对象的有些属性,只有通过认真地研究当前问题域才能得到,例如,平常人们并不十分注意商品的条形码,而在考虑超级市场这类问题域时则会发现它是必须设置的属性。发现对象及其属性、行为定义2.4结合系统软件和将开发的软件确定属性有时,只有具体地考虑系统责任时才能确定对象的某些属性是否需要。在《Object-OrientedAnalysis》一书中曾举过一个生动的例子:作者之一在一个新去过的城市使用信用卡后不久就收到银行的一封信,信中问道:“我们注意到你的信用卡在以前没有使用过的地方使用了,此事是否正常?你的卡没有失窃吧?”