大型应用软件设计报告.docx
《大型应用软件设计报告.docx》由会员分享,可在线阅读,更多相关《大型应用软件设计报告.docx(22页珍藏版)》请在冰豆网上搜索。
大型应用软件设计报告
组内成员及任务描述
学号
姓名
任务
2012301500028
李标
画用例图,活动图,类图,序列图,系统构件图,部分系统设计文档的书写
2012301500017
卢焱鑫
整个系统的编码实现,部分系统设计文档的书写
2012301500008
邓永康
系统需求分析,功能模块设计,数据库设计,部分系统设计文档的书写
2012301500029
童立成
前台测试,后台测试,系统图标美工,部分系统设计文档的书写
第一章餐馆系统的业务建模
1.1非正式的需求
目的:
通过改进为顾客预定和分配餐桌的过程,支持一家餐馆的日常经营。
原始手工系统速度慢,而且预约登记单很快会变得难以理解。
这可能导致经营上的问题,例如,实际上有空餐桌而由于这个预约单不是很明显,会妨碍顾客进行预约;没有备份系统,如果一张预约单被损坏,那么餐桌就没有那个晚上的预约记录。
由于这些以及其他原因,该餐馆欲开发一个预约单的自动化系统。
该系统应该和现有的预约单显示同样的信息,并且有大致相同的格式,使餐馆员工易于转换到新系统。
当记录了新的预约时或对已有的预约进行修改时,应该立即更新显示,使餐馆员工在工作时,总能获得最新信息。
系统必须易于记录餐馆营业时发生的有意义的事情,例如顾客的到来。
系统的操作应当尽可能直接操作屏幕上显示的数据。
例如,可以简单地将一个预约拖到屏幕上的一个适当的位置,来改变分配的餐桌。
1.2用例建模
用例视图应该是客户、最终用户、领域专家、测试人员和任何其他的涉及系统的人员,不需要详细了解系统结构和实现就容易理解的。
用例视图不描述软件系统的组织或结构,它的作用是给设计者施加约束,设计者必须设计出一个能够提供用例视图中指定的功能的结构。
1.2.1用例
可以通过考虑在系统实现后餐馆员工能够用它来做什么,简单地草拟出一组初步的用例。
下面列出了这些用例所支持的主要任务:
1.记录一个新的预约信息(“记录预约”)。
2.取消一个预约(“取消预约”)。
3.记录一位顾客的到来(“记录到达”)。
4.将一位顾客从一张餐台移到另一张餐台(“调换餐台”)。
1.2.2参与者
在餐馆预约系统的案例中,所提出的用例可以分成两组。
第一组由与维护提前预约信息有关的用例组成。
顾客将联系餐馆提前预约或取消提前预约,一般地,接待员将接到这些电话并更新预约系统中存储的信息,因此,我们能够确定一个与相应用例关联的参与者。
在第二组中有许多任务需要在餐馆营业时执行,包括记录顾客的到来,以及为了适应不可预料的经营需要将一行用餐者从一个餐台移到另一个餐台。
这些工作譬如说可能是一个侍者领班的责任,因此我们能够标识另一个与这些用例关联的参与者。
1.2.3用例图
用例图(use case diagram)以图解的形式概括了系统中的不同参与者和用例,并显示了哪些参与者能够参与哪些用例。
餐馆预约系统的初始用例图如图所示:
1.3描述用例
用例描述了系统和它的用户之间在一定层次上的完整的交互。
例如,一个打电话给餐馆进行预约的顾客,会和餐馆的一位将在系统中记录预约的店员讲话。
为此,该店员需要充当一个接待员,即使这并不是他们正式职位的描述,并且以某种方式和系统交互。
在这种情况下,该店员被认为是接待员参与者的一个实例,发生在接待员和系统之间的交互是用例的一个实例。
1.3.1事件路径
用例描述必须定义在执行用例时用户和系统之间可能的交互。
例如,在“记录预约”用例中,基本事件路径将描述这样的情况:
一位顾客打电话进行预约,在要求的日期和时间有一张合适的餐台是空闲的,接待员输入顾客的姓名和电话号码
并记录预约。
这样的事件路径,如下所示,能够以稍微结构化的方式表示,以强调用户的动作和系统响应之间的交互:
记录预约:
基本事件路径
1. 接待员输入要预约的日期;
2. 系统显示该日的预约;
3. 有一张合适的餐台可以使用;接待员输入顾客的姓名和电话号码、预约的时间、用餐人数和餐台号;
4. 系统记录并显示新的预约。
如果在顾客要求的日期和时间没有可用的餐台,上面描述的基本事件路径就不能完成。
在这种情况下会发生什么可以通过一个可选事件路径描述,如下所示:
记录预约——没有可用的餐台:
可选事件路径
1.接待员输入要求预约的日期;
2.系统显示该日的预约;
3.没有合适的餐台可以使用,用例终止。
可选事件路径描述的情况,可以作为营业的一个正常部分出现,它们并没有指出产生了
误解,或者发生了错误。
在另外一些情况下,也许因为一个错误或用户的疏忽而不可能完成基本事件路径,这些情况则由例外事件路径描述。
记录预约——餐台过小:
例外事件路径
1.接待员输入要求预约的日期;
2. 系统显示该日的预约;
3. 接待员输入顾客的姓名和电话,预约的时间,用餐人数和餐台号;
4. 输入的预约用餐人数多于要求餐台的最大指定大小,于是系统发出一个警告讯息询问用户是否想要继续预约。
5. 如果回答“否”,用例将不进行预约而终止;
6. 如果回答“是”,预约将被输入,并附有一个警告标志。
1.3.2用户界面原型
一般而言,在用例描述中详述用户界面不是个好主意。
用例描述的重点是定义系统和用户之间交互的总体结构,而包含用户界面的细节会使之不清晰。
并且,用户界面应该被设计得协调一致并便于使用,而这只有合理地考虑了各式各样的用户任务才能做到。
如果用例描述不适当地指定了用户界面的细节,可能会使用户界面设计者的工作更加困难,或者需要大量改写用例描述。
1.4组织用例模型
一旦已经记录了一个预约,接下来必须要处理的重要事件是顾客到达餐馆,这由我们称为“记录到达”的用例描述。
该用例的基本事件路径如下:
记录到达:
基本事件路径
1. 侍者领班输入当前日期;
2. 系统显示当天的预约;
3. 侍者领班确认一个选定的预约已经到达。
4. 系统对此进行记录并更新显示器,将顾客标记为已到达。
在这个用例中,如果系统记录中没有到达顾客的预约,可能发生一个可选事件路径。
在
这种情况下,如果有适当的餐台是空闲的,则创建一个未经预约的登记。
记录到达——没有提前预定:
可选事件路径
1. 侍者领班输入当前日期;
2. 系统显示当天的预约;
3. 系统中没有记录该顾客的预约,所以侍者领班输入预约时间、用餐人数和餐台号,创建一个未预约登记;
4. 系统记录并显示新预约。
比较这些事件路径和为“记录预约”用例所写的事件路径,显示出在这两个用例中存在着相当数量的某些共享功能。
与其多次写出相同的交互,一种更好的方法是在一个地方定义共享行为并在适当的地方引用它。
UML定义的用例图表示法提供了一些可以这样做的方法,能够产生一个更简单和结构更好的用例模型。
1.4.1用例包含
餐馆经理可能试图计算一个特定的晚上要雇佣多少个侍者,那么,简单地看看当天的预约可能是估计餐馆大约会有多繁忙的一个好办法。
应该定义一个相应于显示给定一天的预约的任务的新用例。
这个用例能够被餐馆的任何工作人员执行,因而任何参与者都可以在下面对基本事件路径的描述中被提及。
显示预约:
基本事件路径
1. 用户输入一个日期;
2. 系统显示当日的预约。
这个新用例和已经描述的用例之间的关系可以这样来描绘:
只要在执行其他用例之一时就包含“显示预约”用例中的交互。
这种关系需要在用例描述和用例图中予以清晰化。
在一个用例描述中,如下面版本的“记录预约”用例的基本事件路径描述的,包含其他的用例可以非形式地说明。
记录预约:
基本事件路径(修改)
1. 接待员执行“显示预约”用例;
2. 接待员输入顾客姓名和电话号码、预定的时间、用餐人数以及预留的餐台;
3. 系统记录和显示新预约。
一个用例和它所包含的其他用例之间的关系在用例图中用一个连接两个用例的虚线箭头表示,称为依赖性(dependency), 用一个指定所描述关系的类型的构造型(stereotype)标记。
下图表示了“记录预约”和“显示预约”之间的“包含(include)”依赖性。
1.4.2参与者泛化
参与者之间泛化的含意是,特化的参与者可以参与和更一般的参与者关联的所有用例。
下图描述了一个新参与者,它表示餐馆所有员工可以共享的能力,因而称为“员工(staff)”。
已有的参与者通过泛化(generalization)与新参与者相关,表示它们被看作是“员工”的特殊情况,定义了只能由一个员工子集共享的附加的特性。
1.4.3用例扩展
“记录到达”用例的可选事件路径规定,如果系统没有记录一个顾客的预约,侍者领班将通过创建一个未预约登记来表示他们在餐馆用餐的事实。
但是,将记录未预约登记表示为单独一个用例可能更好一些,因为未预约登记将会为那些从不提前进行预约的顾客创建,而且该用例可能需要独立于“记录到达”用例执行。
“记录未预约顾客”用例的基本事件路径将会被某个没有预约就来用餐人触发。
它的结构非常类似于“记录预约”用例,只是在记录的细节上不同。
基本事件路径可以如下描述:
记录未预约顾客:
基本事件路径
1. 侍者领班执行“显示预约”用例;
2. 侍者领班输入时间、用餐人数和分配给顾客的餐台;
3. 系统记录并显示新预约。
“记录到达”用例的可选事件路径和这个新用例的描述之间有相当多的重叠。
“记录未预约顾客”用例只是在“记录到达”的某些情况下被执行,也就是对该顾客没有记录的预约、有一个适当的餐台空闲着、并且顾客还想在餐馆用餐时才被执行。
“记录到达”用例可以被“记录未预约顾客”用例扩展,来描述这种情形。
这在用例模型中可以通过一个标记为‘extends’的构造型的依赖性表示,如图所示:
1.5完成用例模型
取消预约的基本事件路径可以如下指定:
取消预约:
基本事件路径
1.接待员选择要求的预约;
2.接待员取消该预约;
3.系统询问接待员确认取消;
4.接待员回答“是”,系统记录取消并更新显示。
“调换餐台”用例的基本事件路径也可以独立于用户界面的细节进行定义如下:
调换餐台:
基本事件路径
1. 侍者领班选择需要的预约;
2. 侍者领班改变该预约的餐台分配;
3. 系统记录改变并更新显示。
这个用例可以通过一个菜单选项调用,由用户在一个对话框中填写新的餐台号,或者通过将预约矩形拖到它的新位置完成调换餐台。
完整的用例图如图所示:
第二章餐馆系统的分析
2.1分析的目的
以用例描述的形式陈述的需求是定义系统外部行为非常有价值的工具,但是它们对系统的内部结构,或如何提出一组交互的对象来支持所要求的功能并没有给出任何指导。
因此,可以把分析的任务描述为是构造一个模型,来说明这些交互的对象如何能够交付用例中规定的行为。
2.2对象设计
为了产生实化一个用例的交互图,必须在一组对象之间分配所需要的数据和处理,那么这些对象就可以进行交互以支持用例规定的功能。
面向对象程序设计的启示是软件对象反映的是在现实世界或应用领域中找出的对象。
面向对象系统中的数据并不是保存在一个单独的中央数据存储中,而是分布在系统的所有对象中。
这可以用责任的术语来描述说每个对象负责管理系统中数据的一个子集。
一个对象负责的数据不仅包括它的属性值,还包括它所维护的与系统中其他对象的链接。
对象负有的另一类责任是支持某些处理,这些处理最终在它的类所实现的方法中定义。
由对象进行的处理典型地包括,在该对象可用的数据上实行某些计算,或者通过给其他对象发送消息协同进行一个较大的操作以及用它们返回的数据做些事情。
对象设计的一个基本原则是,在进行用例实化时,设计者应该定义具有功能上内聚的责任集的对象和类。
本章剩余的部分将举例说明这条原则的应用。
2.3软件架构
定义良好的对象应该有一组内聚的责任。
例如,在餐馆预约系统的情况中,可能会提出建议,顾客对象应该负责任何与顾客有关的事宜,从在屏幕上显示顾客信息,维护顾客的姓名和电话号码使之可以使用,到将这些数据存储到一个关系数据库中。
责任应该交给不同的类,由一个模型(model)类来负责维护数据,而由一个视图(view)类负责显示数据。
在系统运行时对象之间传递的消息数目会增加。
例如,无论何时要更新显示,视图类在显示之前都必须从模型类获取对象最近的状态。
这种在模型和视图之间进行区分的原则可以应用于系统级,导致识别架构中两个分离的层次。
维护系统状态和实现应用业务逻辑的类置于应用层(application layer),而与用户界面有关的类放在表示层(presentation layer)。
2.4用例序列图
2.4.1接待预约序列图
2.4.2临时预约序列图
2.4.3调换餐桌序列图
2.4.4预约餐桌序列图
2.4.5注册序列图
2.5完成分析模型
下图显示了系统的类图,包括来源于进行用例实化的过程中的信息和决策。
这个类图也包括来自领域模型的信息,例如顾客、餐台和预约类之间的关系以及不能重复预约的约束等。
第三章餐馆系统的设计
3.1接受用户数据
预约系统对象是一个应用层的对象,所以实际上消息并不会直接发送到这个对象,所以必须有某个表示层的对象,它的责任是接收用户的输入并转发给控制对象。
表示层的这个接收用户输入的对象可以很合理地描述为一个边界对象。
它表示呈现给一个特定参与者的用户界面。
就预约系统来说,我们假定所有用户使用相同的用户界面,因此将这个类命名为“StaffUI”。
为了执行“显示预约”用例,用户首先要选择一个适当的菜单选项。
这引起一个对话框的出现,在对话框中,用户输入需要的日期,然后单击“OK”按钮将请求提交给系统。
3.2产生输出
“StaffUI”类具有两个不同的角色:
作为边界类,它接收来自用户的消息并将消息转发给控制器类;除此之外,它还充当着视图类的角色,将应用数据或模型呈现给用户,即显示系统的输出。
对输出机制的要求是,只要应用数据的状态改变了,屏幕上对该数据的表示就要更新,使用户所看到的和系统状态是一致的。
解决办法是:
只要应用有什么变化时,由应用类来通知视图类,那么对视图的更新只是在需要时才发生。
3.3持久数据存储
预约需要跨会话存储,这个系统的核心问题是捕获和记录预约信息。
除此之外,还有预约链接的餐桌和顾客对象也需要持久保存。
Table
oid
number
places
Customer
oid
name
phoneNumber
WalkIn
oid
covers
date
time
table_id
Reservation
oid
covers
date
time
table_id
customer_id
为了跟踪类的实例,同时为了确保不创建重复的实例,需要在模型中表示出数据库模式中引入的明确的对象标识符。
为每个持久类定义一个表示持久对象的子类,这个子类新增加一个属性来保存明确的对象标识符。
下图说明了持久性的这种实现的结构,该图显示了对特定的“Table”类定义的两个新类。
3.4详细的类设计
系统类的特征的完整清单以及全部的参数和类型信息,如下图所示:
BookingSystem
-date:
Date
+addObserver(o:
BookingObserver)
+cancel()
+getBookings():
Set(Booking)
+getDate():
Date
+makeReservation(d:
Date,in:
Time,tno:
Integer,name:
String,phone:
String)
+makeWalkIn(d:
Date,in:
Time,tno:
Integer)
+notifyObservers()
+recordArrival()
+selectBooking(d:
Date,tno:
Integer)
+setDate(d:
Date)
+transfer(d:
Date,tno:
Integer)
这个类的基本责任是维护当前预约的集合,即用户能够在屏幕上看到的预约,并且该类支持的操作主要是对这个集合的操作,或是对集合中各个预约的操作。
这些预约自身不是作为这个类的一个属性建模,而是以预约系统类和预约类之间的一个关联建模。
3.5动态行为建模
一个完整的设计应该指定系统中类的结构和行为这两个方面。
类图定义预约系统保存的数据以及数据项彼此相关的方式,并因此给出了系统静态结构相当全面的描述。
关于对象的行为的一些信息则由实化用例所定义并显示在顺序图中,其中显示了特定交互所涉及的对象和消息。
3.5.1消息的顺序:
消息发送给对象的顺序将依赖于对象的环境。
例如,发送给预约系统的消息最终依赖系统用户所采取的行为,而不是依赖系统中执行的任何处理。
3.5.2依赖历史的行为:
某些消息具有在不同时间从一个对象引起不同响应的特性。
例如,在记录一个到达餐馆时,这个预约的到达时间应该相应地设置。
然而,如果随后同样的消息再次发送给相同的对象,将不会改变对象的状态,因为一个预定到达多次没有意义。
让对象负责检查在它的当前状态没有意义的消息。
由于一个消息的效果可以依赖于先前已经发送给它的消息,这意味着对象必须以某种方式知道它们的历史,或者知道它们已经接收的消息。
3.5.3指定行为:
对象行为有两个方面在交互图中没有捕获,但是这需要作为系统设计的一部分明确说明。
1. 对象预期接收什么消息序列。
2. 对象如何响应消息,尤其是这个响应如何依赖于对象的历史,即它已经接收的消息。
3.6预约系统的状态图
预约系统类显示出的最重要的依赖状态的行为与预约的选择有关。
某些消息,如“recordArrival”,只能在已经选择了一个预约的条件下被切合实际地处理。
这种情况的基本动态在下图中定义。
在任一给定的时间,对象总是处于它可能的状态之一。
当它接收到一个消息对应于从它当前状态出发的转换上的事件时,该转移被激发,而对象进入转换另一端的状态。
例如,假定当前没有选择的预约,预约系统处于上图左部所示的“NotSelected”状态。
如果现在发生顾客到达的交互,预约系统会先收到一个“selectBooking”消息,这将引起标记该消息名字的转换被激发,而预约系统对象将迁移到“Selected”被选中状态。
然后,接收到“recordArrival”消息,标记为“recordArrival”的转换激发。
但是,这使预约系统还处于接收消息之前的状态,换句话说,在这个消息被处理之后,对象仍然处于被选中状态。
只有在预约处于被选中状态时才有意义的其他消息是“transfer”和“cancel”。
“transfer”和“recordArrival”的行为方式相同,但是“cancel”的结果略有不同。
一旦取消了一个预约,它将从显示中消除并被删除,所以不会再存在一个选中的预约。
因此,在状态图中,标记着“cancel”的转换必须将系统移回到“NotSelected”状态,如图所示。
3.6.1非确定性
下图说明了收到“selectBooking”消息的所有可能结果。
假定如果在屏幕上一个空位置单击鼠标,任何已选择的预约仍处于选定。
3.6.2监护条件
在被建模的系统中真正存在非确定性的情况下,像3.6.1那样的状态图是完全适合的。
在预约系统的情况中,它完全依赖于和“selectBooking”消息一起传递的参数。
通过为相关转换增加监护条件(guardcondition),在状态图中可以表明这些事实。
图3.6.2说明了如何指定监护条件以解决图3.6.1中的不明确性。
3.6.3动作
下图所示的是带有动作的状态图,以强调新预约将被选择的情况。
3.7预定的状态图
预定类提供了用状态图概括一个类的对象的行为的另一个例子。
预定的确显示出了依赖于状态的行为:
一旦已经记录了到来者,就不可能取消预约,或者再次记录到达。
总结这个行为的状态图如图所示。
这个图中显示了两个状态,“Booked”状态对应于已经进行了预定,但是顾客还没有到达餐馆的时候,而在顾客到达并且系统记录了他们的到达时间时,到达“Seated”状态。
个人总结
李标
这次餐饮系统的设计,我的任务主要是各种UML建模图的设计。
要画出具体的UML图,我们全组成员就必须先要统一设计功能,根据各个功能画出建模图,以此使得代码设计、软件架构更加科学、更加简洁。
这次我们要画的图主要包括用例图、活动图、序列图、类图等,通过此次UML建模方法的使用,我对于软件的设计方法、软件结构的设计、代码的简化等方面有了更深刻的认识。
软件设计的主要目的并不仅仅是让我们编程出应用程序,而是让我们在软件设计上建立起我们更深刻的认识,让我们能够在一个更高的角度上设计出高质量的软件。
卢焱鑫
这次软工实验我负责的部分是代码编写,首先仔细阅读老师提供的需求ppt,然后小组内讨论总结出需要实现的功能,分配好任务之后开始代码的编写,根据之前项目里Android相关内容的经验我决定用java写一个简单的Android上的APP,利用Sqlite数据库的使用完成对于用户信息以及餐桌信息的相关操作,总体来说实现的功能比较简单,但实现的过程也不是一帆风顺,经常会遇到数据库方面的bug和异常,在反复的调试之后终于得以完成,这是自己完成的一次挑战和对之前所学知识的一次练习,也是小组成员共同努力的结果。
邓永康
通过这次大型软件设计实验,我对软件开发有了一定的了解,从需求分析,系统设计,系统实现,到测试,每一个过程都需要下工夫,查阅相关文献。
需求分析写的相当简单,粗糙,以后需要进一步改进。
软件开发不仅仅是编程,必须要充分了解客户需求并事先想到一切可能出现的问题,才能使开发出迎合大众的软件。
虽然这次实验漏洞百出,但是为今后的大型软件开发打下了基础。
童立成
本次实验主要进行实验过程的功能实现测试与错误提交,细节方面的调试需要整个团队的任务交流,交互关系与代码的层次分析,视图更新,外观设计与逻辑整理,Android有些内容第一次接触难免有些生疏,关键内容的修改还得益于团队成员的合作。
整个实验周期较长,以及经验缺乏,文档的书写尽量按照实验过程顺序记录,得益还是很多,下次希望能有更好的成就。