接下来,我们来抽丝剥茧,逐句分析用例规约。
1. 当到达时间周期①时,系统②选择下一个适合发邮件的发件邮箱③以及下一个待发往的邮箱地址④
1. 时间周期缺省为5秒⑤
1. 定位适合发邮件的发件邮箱的规则:从正在生效的通知任务⑥指定的发件邮箱⑦中找出以下值最大而且值大于0的邮箱: (当前时间-邮箱上次发送时间⑧)-邮箱最小发件时间间隔⑨
1. 定位下一个待发往的邮箱地址的规则:针对正在生效的通知任务,随机选取符合以下条件的邮箱地址:联系人⑩符合公开课⑪通知任务条件,而且联系人有邮箱地址尚未被正在生效的通知任务通知。
1. 联系人符合公开课通知任务条件的规则:联系人当前所在城市⑫所属分区⑬与公开课举办城市⑭所属分区相同,而且联系人不属于“拒绝公开课通知联系人”⑮,而且联系人不属于该公开课“已通知联系人”⑯,而且联系人当前所在组织⑰不属于该公开课“已通知的组织”⑱。
①时间周期。这是执行用例“发送公开课通知”的时间周期,可以看作和时间交互的边界类的一个属性。
图8-23 UMLChina系统类图1
②系统。在分析工作流中,“系统”的概念已经被打碎成各个类,所以“系统”这个词不需要识别成类。
有些开发人员在这里会犯错误,把“系统”识别成一个类,画成这样:
图8-24 无意义的类图
这个图只是简单功能分解的另一个变体,对剖析系统的复杂性没有帮助,却给开发人员带来一种虚假的成就感:我描述了几个类之间的关系,而且还是组合关系,已经开始剖析系统的复杂性了呢!
“系统”的概念是需求工作流的概念。在需求工作流,我们把系统看作一个整体对外提供服务。
工作流 | 如何称呼当前要开发的系统 | 原因 |
业务建模 | 某某系统 | 研究对象是组织,组织中有很多系统,需要指出系统的名字。 |
需求 | 系统 | 研究对象是当前要开发的系统,不需要再说名字。 |
分析 | 很多个类 | 研究焦点进入系统的内部,思考系统内部的构成。 |
图8-25 如何称呼当前要开发的系统
③下一个适合发邮件的发件邮箱。“发件邮箱”映射成类。”下一个适合发邮件的“前面加一个”是否“,映射成类的状态属性,深入建模后,再消除这些状态属性。
图8-26 UMLChina系统类图2
④下一个待发往的邮箱地址。“邮箱地址”本来应该是“联系人”的一个属性,但“下一个待发往的”这个定语说明“邮箱地址”有“是否下一个待发往”这样的状态属性,另外考虑到联系人会有多个不同用途的邮箱地址,所以把“邮箱地址”独立出来变成一个类,“是否下一个待发往”作为“邮箱地址”的状态属性。
图8-27 UMLChina系统类图3
⑤时间周期缺省为5秒。映射为“时间周期”属性的缺省值。
图8-28 UMLChina系统类图4
为了防止滥发邮件,邮箱提供商会规定每个邮箱每天发送邮件总量以及发送时间间隔,如果违反规定,邮件会暂时无法发出,邮箱甚至会被关闭。过于频繁地检测是否有符合条件的发件邮箱,没有意义,但如果检测时间间隔太长,会导致可以发邮件时发件邮箱却空置,影响发邮件的效率。5秒应该是合理的值。
⑥正在生效的通知任务。“通知任务”映射成类,“是否正在生效”映射成状态属性。
图8-29 UMLChina系统类图5
⑦指定的发件邮箱。“通知任务”关联到“发件邮箱”。
图8-30 UMLChina系统类图6