第1页:第7章 类的详细设计封面
第7章 类的详细设计封面
本页为《第7章 类的详细设计》课件的封面页,围绕方法级详细设计展开,覆盖图形、表格、语言三类工具与状态图、OCL约束。
第2页:第7章 类的详细设计
第7章 类的详细设计
- 第7章类的详细设计
- 详细设计是以概要设计说明书作为基础,完成各模块的算法设计、用户界面设计以及数据结构设计的细化等。
- 对于开发者来说详细设计的主要工作就是在每个类的方法中补充对应的业务实现。
- 类中方法的设计,使用状态图对类的行为,使用OCL对类的实现细节进行准确定义。
第3页:详细设计的主要活动
详细设计的主要活动
- 为每个模块进行详细的算法设计。用某种图形、表格、语言等工具将每个模块处理过程的详细算法描述出来。
- 为模块内的数据结构进行设计。对于需求分析、概要设计确定的概念性的数据类型进行确切的定义。
- 为数据结构进行物理设计,即确定数据库的物理结构。物理结构主要指数据库的存储记录格式、存储记录安排和存储方法,这些都依赖于具体所使用的数据库系统。
第4页:详细设计的主要活动
详细设计的主要活动
- 其他设计:根据软件系统的类型,还可能要进行以下设计:输入/输出格式设计;人机对话设计;对于一个实时系统,用户与计算机频繁对话,因此要进行对话方式、内容、格式的具体设计等。
- 编写详细设计说明书。
- 评审。对处理过程的算法和数据库的物理结构等进行评审。
第5页:类方法的详细设计
类方法的详细设计
- 结构化的程序如果程序的代码块仅仅通过顺序、选择和循环三种控制结构进行连接,并且每个代码块只有一个入口和一个出口,则称这个程序是结构化的。ABEFGCDHABEFG非结构化程序设计5
- 目的是简化设计过程,仅使用有限的可预测的操作即可完成相应的算法流程
第6页:图形设计工具
图形设计工具
- 程序流程图(flowchart)
- 简单、直观、易于学习ABCBATFCBAT6F
- 应尽量保持结构化的特点,限制控制流的随意跳转
- 适当使用goto、break、continue等语句
第7页:图形设计工具
图形设计工具
- 盒图(NS)
- 一种符合结构化程序设计原则的图形描述工具
- 不允许随意跳转
- 通过组合嵌套方式构成更大的“盒子”
- 复杂逻辑绘制繁琐ABCConditionTrueFalseABCaseConditionVx...V3V2V1X...CBAWhileConditionAUntilConditionAA
第8页:图形设计工具
图形设计工具
- 问题分析图(PAD)
- 使用二维树形结构的图来表示程序的控制流,绘制方便
- 结构清晰,翻译到代码较为容易ABCABCon-ditionTrueFalseAB...XV1V2Case...VxAWhileConditionAUntilConditiondef
第9页:表格工具
表格工具
- 判定表是一种进行详细设计的表格工具,又称为决策表。
- 判定表适用于描述判断条件较多,各条件又相互组合、有多种决策方案的情况。
- 判定表有着准确而又简洁的描述方式,能够将复杂的条件组合与对应的执行动作相对应。
- 例如:某工厂机器维修的方式:对功率大于50马力的机器或已运行10年以上的机器,应送到专业的维修公司处理;否则如果功率小于20马力,并且有维修记录,则在车间维修;否则送到本厂的维修中心维修。
第10页:判定表示例
判定表示例
本页以图示为主,源图为课件中的模型图或示意图,图中文字标注如下。
判定表示例121110987654321规则#CCCCBBBBAAAA机器功率wNNYYNNYYNNYY运行时长<10年?YNNYYNNYYNNY有维修记录※※※※※※※※送外维修※※※本厂维修※本车间维修A:w>50,B:w<20,C:20≤w≤5010
第11页:判定表构成
判定表构成
- 判定表有4个部分构成,分别是条件列表、条件组合、动作列表及动作入口;
- 每个条件对应一个变量、关系或者预测,如上例中的机器功率、运行时长、维修记录;
- 条件组合是各种条件可能取值的所有组合,如果每个条件有真假两种取值,则n个条件的取值组合数量为2n个;
- 动作指要执行的过程或操作列表,如上例中的送外修或者送本厂维修中心;
- 动作入口指某个条件组合下与动作的对应,与条件组合一起构成了判定表的一列,也叫做规则。
第12页:判定表化简
判定表化简
本页以图示为主,源图为课件中的模型图或示意图,图中文字标注如下。
- 判定表化简1254321规则#BCB—A机器功率wNNNYN运行时长<10年?Y—N——有维修记录※※送外维修※※本厂维修※本车间维修A:w>50,B:w<20,C:20≤w≤50
- 使用“—”来表示对此条件的不关心或不适用
- 任意两个条件组合之间不能有交集
第13页:判定树
判定树
- 判定表虽能表示复杂的条件组合与动作之间的对应关系,但其含义却不是一目了然,理解它也要有一个学习过程。
- 当数据元素值多于两个时(如功率),判定表的简洁程度也将下降。
- 判定树是判定表的变种,也能清晰地表示复杂的条件组合与应做的动作之间的对应关系。运行时长(>10年?)送外维修机器功率w(马力)送外维修本厂维修有维修记录?本厂维修本车间维修YesNoW>50W<2020<=w<=50YesNo
第14页:判定树
判定树
- 判定树又称为决策树,是应用于数据分类的一种树结构。
- 其中的每个内部结点(internalnode)代表对某个属性的一次测试,每条边代表一个测试结果,叶结点(leaf)代表某个类(class)或者类的分布(classdistribution),最上面的结点是根结点。
- 判定树提供了一种展示类似在什么条件下会得到什么值这类规则的方法。
- 最佳判定树的寻找是一个NP困难问题,经典的算法有ID3算法,即决策树归纳(InductionofDecisionTree)。
第15页:语言工具
语言工具
- 程序设计语言(ProgrammingDesignLanguage,PDL)是一种用来进行详细设计的语言类工具,又称为结构化语言或伪代码。
- 与自然语言相比,PDL借用某种编程语言的语法构筑其逻辑流程;
- 与编程语言相比,其中又使用了自然语言的词汇(如英语)。
- PDL不能被编译或解释运行,主要是供开发人员使用的。
第16页:PDL特点
PDL特点
- PDL采用关键字的固定语法,提供了结构化控制结构、数据说明和模块化的特点。
- PDL程序中会有一些能够标明程序结构的关键字。
- PDL语言仅有少量的简单语法规则,大量使用人们习惯的自然语言。
- 使用PDL语言常常按逐步细化的方式写出程序。
- PDL程序的注释行对语句进行解释,起到提高可读性的作用。
第17页:PDL伪码示例
PDL伪码示例
本页以图示为主,源图为课件中的模型图或示意图,图中文字标注如下。
- 1:172:3:4:5:6:7a:procedure:sortdowhilerecordsremainreadrecord;ifrecordfield1=0thenprocessrecord;storeinbuffer;incrementcounter;elseifrecordfield2=0thenresetcounter;elseprocessrecord;storeinfile;endifendif7b:enddo8:endPDL示例
- PDL最大的优势是容易翻译成某种编程语言描述的代码,如C、Java等。
- 但PDL不是编程语言,因此不必过多担心存在语法错误,而是将精力集中在设计上。
- PDL作为设计工具没有图形工具形象和直观,但其表现形式是最接近代码实现的一种形式。
第18页:类的详细设计
类的详细设计
- 一些方法的返回值对实例变量值没有任何影响,把这些类的实例对象称为无记忆对象(memoryless)或无状态对象(stateless)。
- 相反,一些对象的功能需要依赖于其内部状态,把这类对象称为是有记忆对象或者有状态对象。
- 对象的状态以及状态变化可以借助状态图(StateDiagram)或有穷状态机(FiniteStateMachine)进行描述。
第19页:状态图的基本结构
状态图的基本结构
- 左侧描述的是状态的一般构成模板,右侧是一个具体的状态。
- 应含有一个唯一的开始状态,可以有多个结束状态,开始状态和结束状态统称伪状态。
- 状态图中的状态变化都是针对确定性行为的描述。开始状态结束状态生日entry/购物do/庆祝exit/打扫状态名entry/进入该状态执行的动作do/处于该状态执行的活动exit/离开该状态执行的动作事件[条件] /动作
第20页:状态
状态
- 每个状态描述中除了状态名字以外,还可以包含以下三个预定义的事件的描述:
- Entry:给出当刚进入该状态时应该进行的动作(action)。在这里可以表示一个简单的赋值操作,也可以是对一个或多个方法的调用。
- Do:给出在保持该状态的过程中,对象应执行的活动。这个部分一般对那些受时间控制行为的对象比较适用,因为它们通常要求能够持续的读取信息。
- Exit:这个部分描述当离开该状态时应进行的动作。
- 这三个部分的内容是可选的,根据需要进行取舍。
第21页:状态转换
状态转换
- 状态通过状态转换进行过渡(Transition)。
- 事件部分:转换的主要内容,状态图主要是对被动系统的行为描述,对外界的刺激事件进行相应的响应。
- 条件部分:状态间的转换只有在事件被触发并且满足某个特定条件的情况下才会进行,可选。
- 动作:表示当转换发生时执行的一个动作,该动作执行的时机是在转换对应的目标状态的entry事件被执行之前,即还未进入到目标状态前。
第22页:类Project的状态图
类Project的状态图
本页以图示为主,源图为课件中的模型图或示意图,图中文字标注如下。
类Project的状态entry/项目初始化entry/addSubproject()entry/addPredecessor()entry/addTask()entry/setCompeletePct()entry/setRealEffort()完成度设置项目执行工作量更新子项目添加前置子项目设置任务添加项目计划项目结束entry/archieveProject()项目创建更改完成度更改工作量22结束计划结题[具有前置项目]新建子项目[没有前置项目]新建任务新建项目
第23页:状态图的扩展
状态图的扩展
- 状态图本身如果过于庞大,容易让人陷入局部而丢失整体上的可理解性。
- 一种经常见到的情况是状态图中若干状态在同一事件作用下具有相同的行为,比如对于异常的处理或者运行的停止。
- 状态可以以一种层次化的方法进行组织,每个状态通过多个子状态细化,该状态称为复合状态。
- 复合状态中的所有子状态只需一个转换来描述共同行为,节省了转换的个数,同时使得图形的绘制保持整洁,不会过于杂乱无章。
第24页:状态图扩展示例
状态图扩展示例
本页以图示为主,源图为课件中的模型图或示意图,图中文字标注如下。
entry/archieveProject()entry/addSubproject()entry/addPredecessor()entry/addTask()entry/setCompeletePct()entry/setRealEffort()项目创建entry/项目初始化活动项目工作量更新完成度设置任务添加前置子项目设置子项目添加项目结束项目执行项目计划新建项目24项目取消更改完成度更改工作量新建任务[没有前置项目][具有前置项目]新建子项目结题结束计划
第25页:并行子状态的描述
并行子状态的描述
- 对象状态也可能是由多个互不依赖的子状态构成的。
- 每种可能的行为变化,可使用独立的状态图分别进行描述。
- 每个子状态图相互独立,组合在一起又构成了一个全局的状态。
- 使用并行的组合方式减轻状态图的描述负担。24小时制/秒12小时制/秒24小时制/日期12小时制/日期downdowndownupupdownupup秒日期24小时制12小时制时钟down25downupup
第26页:并行状态的考虑
并行状态的考虑
- 如果一个事件在两个子状态图中都需要进行处理,为两个子状态图建立一个到各自结果状态的转换。
- 从含有并行组合的状态出发的转换表示只有当其含有的所有子状态图都位于结束状态时,该转换才会被触发。
- 如果某个复合状态中的一个子状态图的分支导致离开了此复合状态,则所有的子状态图都将结束。也就是说如果离开其中的一个子状态,其它所有的都将自动结束。
第27页:带有时间控制的状态图
带有时间控制的状态图
本页以图示为主,源图为课件中的模型图或示意图,图中文字标注如下。
- 双击entry/so.start()
- 带有时间控制的状态图,可以将间隔时间或发生的次数作为条件和动作执行的依据。左键按下[非选中对象so]27左键按下[选中对象soandtime<0.5s]左键按下[time>=0.5s]左键按下单击entry/so=selectedObject()
第28页:状态图应用
状态图应用
- 点火器组件能够发出start和end信号;自动控制器能够发出on和off信号;离合器能够发出空转或者负载的信号。
- 外部温度通过传感器连续测量,存于本地温度变量中。
- 启停控制器本身会产生信号motor_on和motor_off,并作为动作输入给电机控制器。点火器离合器自动控制器启停控制器{start,end}{on,off}{空载,负载}电机控制器{motor_on,motor_off}
第29页:启停控制状态图示例
启停控制状态图示例
- 待机节能运转自动启停行进启动工作中静止end/motor_off负载/motor_on空转[3<温度<30]/motor_offoff/motor_ononon/motor_on负载空载负载/motor_onstart
- 电机自动启停控制系统的主要状态变化,电机运转时可自动待机节能,如电机加电空载的时候。
- 对条件也进行了指定,如当电机在外部温度范围在3-30度时允许自动待机。
第30页:操作界面的状态描述
操作界面的状态描述
- 操作界面的状态描述用户名密码登录登录失败,请重试!回到开始登录失败应用运行初始界面登录[验证失败]回到开始退出
- 状态用来表示每个独立的图形界面,事件是用户的输入,如某个按键的按下,进而弹出另外一个界面,即到达了一个新的状态。登录[验证成功]
第31页:对象约束语言
对象约束语言
- 很多业务需求和规则无法利用模型本身的机制进行描述,如“项目类不能以自身作为其子项目”。
- UML提供一种对每个对象进行具体条件的约束机制,如:-projectnumber:int{projectnumber>=0}
- 以上方法会使类图不够简洁,而且复杂业务规则也不能清晰描述,因此引入了OCL。
- 这里引入一个新的类图作为例子:
第32页:课程状态枚举类示例
课程状态枚举类示例
本页以图示为主,源图为课件中的模型图或示意图,图中文字标注如下。
正常结课取消<<enumeration>>课程状态-姓名:String-学号:int-专业:String-是否修学期:boolean+课程注册(v:课程) :void+考核合格课程() :ArrayList+已选课程数() :int+是否已选(v:课程) :boolean+是否理论课程已通过() :boolean学生-日期:Date-分数:double学习情况-课程名:String-状态:课程状态课程-名字:String-是否出国:boolean教授1*-选课学生-所选课程3..**讲授32选课关联类,只与其对应的一个学生对象和一个课程对象具有联系。
第33页:学号约束的OCL描述
学号约束的OCL描述
本页以图示为主,源图为课件中的模型图或示意图,图中文字标注如下。
- 学号要求至少五位数字长,并且构成学号的数字要大于或等于10000。若使用OCL进行描述:contextStudentinvregStudentId:self.stuId>=10000
- 关键字context表明此段OCL的描述与哪些UML对象或类相关。
- 关键字inv表示这是不变的(invariant),也就是说所有的Student对象都要遵守这个约束
- self关键字指的是对context对象的引用,正如在Java中的this或C++中的*this的作用一样。contexts:Studentinv:s.stuId>=1000033
第34页:OCL的包组织方式
OCL的包组织方式
本页以图示为主,源图为课件中的模型图或示意图,图中文字标注如下。
- 将OCL同样以包的形式进行组织,便于使用和管理:packagecom::myCompany::mySWcontextStudentinv:contextStudentinv:endpackage
- 除了实例变量的约束外,OCL同样可以对实例的方法进行,描述方法执行的条件,如未休学的学生至少要选择一门课程:contextStudent::selectedLectures():Integerprestustatus:self.freesemester=falsepostselectedLectures:result>034
第35页:选课总数的OCL后置条件
选课总数的OCL后置条件
本页以图示为主,源图为课件中的模型图或示意图,图中文字标注如下。
- 当该生选择了一门之前没有学过的课程时,该生选课总数加一:contextStudent::registerLecture(v:Lecture)pre:notSelected(v)post:self.selectedLectures()@pre=self.selectedLectures()–1
- @pre表示引用的是方法执行之前的状态值。35相关方法取值示例类型名and,or,xor,notimplies,ifthenelseendiftrue,falseBoolean*,+,-,/,abs()1,-2, 50,464646Integer*,+,-,/,floor()3.14, 42.42,-99.99RealConcat(),size(),substring()‘Hello’,‘Dalian’,‘’String
第36页:授课教授状态的OCL约束
授课教授状态的OCL约束
本页以图示为主,源图为课件中的模型图或示意图,图中文字标注如下。
- 某门课的授课教授在上课时是不能在国外的:contextLectureinv:self.status=Lecturestatus::runningimpliesnotself.prof.inForeign
- 关键字implies表示“if-then”的条件说明。
- 对于一个结课的课程成绩要求分数在1-5之间,可以进行如下的描述:contextExaminationinv:self.selectedLecture.status=Lecturestatus::closedimplies(self.note>=1.0andself.note<=5.0)
第37页:OCL支持的集合类型
OCL支持的集合类型
本页以图示为主,源图为课件中的模型图或示意图,图中文字标注如下。
- OCL目前只支持一些标准集合类型,如Collection、Set、OrderedSet、Sequence以及Bag。collection->method(parameter)
- 一个学生在一个学期内最多可以选择12门课程:contextStudentinv:Student.selectedLecture->select(s|s.status=Lecturestatus::running)->size()<=12
- 竖线前的s变量为一个循环变量,用于遍历集合student.selectedLecture中的每一个元素。
- 返回来的集合又进一步使用了size()方法,提供所含元素数量的整型值。
第38页:存在理论课程的OCL描述
存在理论课程的OCL描述
本页以图示为主,源图为课件中的模型图或示意图,图中文字标注如下。
- 如果在已考试的课程中存在“理论”课程,则方法hasTheoryLect()返回真值:contextStudent::hasTheoryLect():Booleanpost:result=self.examination->exists(p|p.note>=60andp.selectedLecture.title='Theory')
- 要求方法passedLectures()返回的所有课程必须是已经修过的课程:contextStudent::passedLectures():Collectionpost:result=self.examination->select(p|p.note>=60)->iterate(p:Examination;res:Collection=Collection{}|res->including(p.selectedLecture))
第39页:OCL小结
OCL小结
- 以OCL作为约束的构建时,如果有一些编程经验会使其这个构建过程变得简单。
- OCL是一种条件约束语言,因此并不能直接从OCL翻译到具体的代码实现;
- 又由于OCL是一种描述性语言,因此对于建模来说可视情况进行指定,并不需要强制给出。
第40页:本章作业
本章作业