DDD领域驱动设计批评文集>>
《软件方法》强化自测题集>>
《软件方法》各章合集>>
9.1.6 分析类图
从“学员→回答问题”用例规约的基本路径到业务规则部分提炼。我们给关键词加下划线,逐个分析。
注意:加下划线只是为了在书中讲解方便,实际建模工作中不需要这样做,只需要看着需求规约或其他素材,一点点提炼。
9.1.6.1 步骤1及其补充约束
用例规约:
1. 学员提交回答。
1. 回答选择了题目的某个或若干个选项。
提炼:
*学员
这里的“学员”是执行者,指外面那个和系统交互的人肉系统“学员”,而不是系统内部维护学员相关信息和规则的“学员”类——有没有这个类,目前还不能判断。
执行者映射的是边界类,如图9-10:
图9-10 执行者映射边界类
*回答
“回答”提炼为类;
*回答选择了题目的某个或若干个选项。
“题目”、“选项”提炼为类;
“回答”关联“选项”,关联名称可以叫“选择”,“回答”和“选项”的多重性均为*;
“题目”关联“选项”,“题目”的多重性为1,“选项”的多重性为*。
在没有足够证据时,关联一律表示为普通关联。
图9-11 回答、选项和题目
9.1.6.2 步骤2及其补充约束
用例规约:
2. 系统验证回答有效。
2. 有效规则:回答选择的选项必须属于同一道题目;单选题的回答只能是1个选项,多选题的回答至少有2个选项。
提炼:
*系统
如第8章知识点所述,“系统”不识别。
*有效
“有效”是一个形容词,可以作为某个类的状态。此处“有效”描述的是“回答”,映射为“回答”类的“状态属性”。后面深入建模时,会通过状态机中的状态来取代这些“状态属性”。
*回答选择的选项必须属于同一道题目
图9-11无法对此做出约束,需要对“回答”加一个约束,例如:
(from 选项 in 选项s select 选项.题目).Distinct().Count()<=1
*单选题的回答只能是1个选项,多选题的回答至少有2个选项
“单选题”、“多选题”可以提炼为类,作为“题目”的子类,如图9-12。
图9-12 单选题和多选题
提炼“只能是1个选项”、“至少有2个选项”背后的领域概念——“回答选项个数下限”、“回答选项个数上限”,把1、2等具体数字消除掉。
“回答选项个数下限”、“回答选项个数上限”是哪个类的属性呢?如果作为“题目”或“单选题”、“多选题”的属性,会导致有很多“题目”对象的这两个属性值相同。
可以应用第8章讲述的泛化转换为关联的知识,添加一个“类类型”类叫“题型”,同时去掉泛化关系。“回答选项个数下限”、“回答选项个数上限”作为“题型”的属性。
“题目”关联“题型”,“题目”的多重性为*,“题型”的多重性为1。
图9-13 题型
“单选题的回答只能是1个选项,多选题的回答至少有2个选项”这条关于“有效”的规则,可以表达成“回答”的一个约束,例如:
选项s.Count>=选项s.FirstOrDefault().题目.题型.回答选项个数下限 && 选项s.Count<=选项s. FirstOrDefault().题目.题型.回答选项个数上限
这个约束以及上面的约束,都会体现在“回答”的行为中。后面我们还会再讨论。
9.1.6.3 步骤3及其补充约束
用例规约:
3. 系统判分,保存判分结果。
3. 判分结果=学员 回答选项集 得分。
3. 判分规则:所回答选项集和题目预设正确选项集完全相同,则得到该题全部分值,否则该题得分为0。
*分值:某个知识点会有一组题目让学员回答,同一组题目中,可根据题目难度为题目设置不同的分值,难度越大,分值越高。难度是相对的,同一道题目,放在A组可能属于难题,放在B组可能就相对容易。
提炼:
*学员
“学员”提炼为一个类,和“回答”关联,“学员”多重性为1,“回答”多重性为*。
*得分
提炼为“回答”的属性。
图9-14 添加“学员”
*题目预设正确选项集
系统需要记住某道题的哪些选项是答案,可以给“选项”增加一个属性“正确”。
图9-15 给选项添加“正确”属性
注意,这种情况下,“选项”和“题目”的关联中,“选项”只能属于一道“题目”。如果可以多个“题目”共享“选项”,那么“正确”的值将无法确定。
如果一定要共享“选项”的内容,可以增加一个类“命题”(或“陈述”),把“内容”作为“命题”的属性。“选项”和“命题”关联,“选项”多重性为*,“命题”多重性为1。“选项”关联到的“命题”和“题目”决定“选项”的“正确”,(命题,题目)→正确。
例如,针对命题:“挂号”是用例。如果题目说“研究对象为医院”,那它作为选项有可能是错误选项,如果题目说“研究对象为医院信息系统”,那它作为选项有可能是正确选项。更直接的例子,问“以下选项正确的是”和“以下选项错误的是”时,选项是否正确刚好是颠倒的。
此时模型应该是这样:
图9-16 另一种选择
可能有人会想到图9-17两个关联的做法,不过这个做法并不合适。“正确”是由(命题,题目)的关联决定的,正确选项必须是选项的子集。如果像图9-17这样使用两个独立的关联,就有可能出现某道“题目”的“选项”集合是{1,2,3,4},而“正确选项”集合却是{5,6}的矛盾。
图9-17 第三种选择
我们决定采用图9-15的做法,不需要“命题”类,“内容”和“正确”都作为属性“选项”的属性。也就是说,不共享选项的内容,当多道题目的选项内容相同时,重复其内容。
*分值:某个知识点会有一组题目让学员回答,同一组题目中,可根据题目难度为题目设置不同的分值,难度越大,分值越高。难度是相对的,同一道题目,放在A组可能属于难题,放在B组可能就相对容易。
“分值”是谁的属性?从“该题全部分值”看似乎是“题目”的属性,但从“同一组题目中,可根据题目难度为题目设置不同的分值”又可以得知,“题目”不能决定“分值”,而是(题目组,题目)→分值,需要一个能决定(题目组,题目)的类,我们把这个类叫“试题”,题目组可以称为“试卷”。
虽然案例中的场景和常见的考试比起来,没那么正式也没那么严肃,但本质上是一致的。我们这个考试有奖品,正式的考试奖品更大,可能是奖学金,可能是升学资格,可能是编制。
“试题”和“试卷”关联,“试题”的多重性为*,“试卷”的多重性为1;“试题”和“题目”关联,“试题”的多重性为*,“题目”的多重性为1。
因为回答的得分和试题的分值有关,而一道题目可以对应多道试题,通过原有的“回答→选项→题目”无法导航到特定的试题。
这个时候,有必要把“回答”和“试题”关联,“回答”的多重性是*,“试题”的多重性是1。
图9-18 试题
之前关于回答有效的约束表达式也会发生变化:
//选项最多只属于一道题
(from 选项 in 选项s select 选项.题目).Distinct().Count()<=1
//选项的题目和试题的题目是同一道题
选项s.FirstOrDefault().题目==试题.题目
//选项的个数符合要求
选项s.Count>=试题.题目.题型.回答选项个数下限&& 选项s.Count<=试题.题目.题型.回答选项个数上限
//判断是否答对,即选项集等于题目正确选项集
选项s Equal (试题.题目.选项s.Where(选项 => 选项.正确))
9.1.6.4 步骤4及其补充约束
用例规约:
4. 判分结果=学员姓名 得分 评价。
4. 评价从得分值所在的分值区间适用的评价集合中随机抽取。
*评价是一些用于活跃气氛的热门用语,用于评价学员的得分。例如:
得0分,评价可能有“抛开事实不谈”、“不讲武德”、“耗子尾汁”、“你站在此处不要动”等;
得1-2分,评价可能有“打工是不可能打工的”、“个个都是人才”、“维持一下生活这样子”等;
得3-4分,评价可能有“下赛季你防詹姆斯”、“人类高质量男(女)性”、“yyds”等。
提炼:
*姓名
提炼为“学员”的属性。
*评价
提炼为类“评价”。
*分值区间
提炼为类“分值区间”,属性为“下限”和“上限”。“分值区间”和“评价”关联,“分值区间”的多重性为1,“评价”的多重性为*。
图9-19 分值区间和评价
[推荐升级]23套UML EA和StarUML的建模示范视频-全程字幕(2022.6.1更新)
7月7-10晚网课:软件需求设计方法学全程实例剖析
7月21-24晚剔除“伪创新”的领域驱动设计-网络公开课
《软件方法》书中自测题-题目全文 分卷自测(1-8章)16套111题
《软件方法》强化自测题集110题
CTO也糊涂的常用术语:功能模块、业务架构、用户需求……[20210217更新]
如何选择UMLChina服务