UML 主要由5个视图(views)和8个图(diagrams)以及若干模型元素和通用机制等部分构成。这5个视图分别为:用例视图(use case view),逻辑视图(logical view),组件视图(component view),并发视图(concurrency view),部署视图(deployment view),其中用例视图起核心作用,因而很多人也把这5个视图称为4+1视图。
用例视图用于描述系统应有的功能集合,主要为用户、设计人员、开发人员和测试人员而设置。它是从系统外部用户的观点看系统功能的抽象表现。
逻辑视图也称设计视图,用来显示系统内部支持实现用例视图功能的逻辑结构。主要为设计人员和开发人员使用。
组件视图也称开发视图,用来显示系统内部组件的模块结构。为开发人员使用。
并发视图也称过程视图,用来显示系统内部在实现功能时各个对象的协作关系。为系统集成人员和开发人员使用。
部署视图,用来显示系统的组件在物理上的配置,例如数据库服务器、用户端软件、网络配置等。为系统集成人员、开发人员和测试人员使用。
8个UML 图可分为3个静态图和5个动态图。静态图:类图(class diagram);组件图(component diagram);部署图(deployment diagram)。动态图:用例图(use case dia gram);状态图(state diagram);顺序图(sequence diagram);活动图(activity diagram);协作图(collaboration diagram)。
3.5.2功能需求分析和用例分析
在总体需求下,功能分析是分析更具体的最终使用者的需求。这里最终使用者是泛指使用该系统实现某类功能的人员。在UML 中,这类人员称为角色。
3.5.3流程分析和界面设计
如何实现软件需求,也就是实现用例图中规定的功能,这就需要进行流程分析,并在此过程中设计用户界面。下面以注册用户添加一条血压测量记录为例进行流程分析,其所需步骤或者所谓流程为①注册用户登录;②选择编辑记录;③选择添加记录;④保存记录。这4个步骤,可以用UML 的活动图39来表示。从开始到结束要经过登录-用户功能选择-编辑记录-添加记录这4个步骤,我们可以很自然地设想每个步骤都需要系统提供用户界面(graphical user interface,GUI)。虽然用户界面的设计可以是多样的,好的美工设计可以使用户界面更悦目和友好,但是每个用户界面上所必须的内容却是相当确定的。
登录界面:要有输入用户名和密码的文本框,确认和撤销的按钮,如果更仔细一些,还可以有忘记密码的处理提示和新用户注册的链接。
选择功能界面:至少要有选择6个相应功能的按钮(或使用类似功能的其他选择方法控件),还要有不选择而退出操作的控件。
编辑功能界面:至少要有选择3个相应编辑功能(添加、删除、更新)的按钮(或使用类似功能的其他选择方法控件),还要有返回上一页面的控件以及不作任何选择而退出操作的控件。
添加记录界面:需要有所有记录内容的控件,比如其中要有选择何种记录(血压、血糖等),当选择血压时,页面上至少需要输入舒张压、收缩压和测量时间的文本框或提供类似功能的控件。
遍历所有用例图,我们可以确定我们需要的所有用户界面,并对每个界面进行较深入的功能设计。
活动图是UML 中用来跟踪用例流程的诸多手段之一。其他如顺序图、协作图等也都常常被用作跟踪流程、设计用户界面的手段。
3.5.4对象分析和定义
计算机发展起始阶段,计算机软件技术是面向过程的技术,而现代软件技术则是面向对象的技术,它更真实而客观地描述了世界。
我们所处的世界是由对象组成的,没有一个事物不属于对象,对象无处不在。计算机软件就是客观世界的某个片断在计算机里的模拟。对象是对客观事物的抽象描述。
对象具有静态特征和动态特征。静态特征用数据描述,称作对象的属性;动态特征是对象的行为和功能,称作对象的方法或操作。一个对象由一组属性和一组行为(功能、方法)组成。对象是由属性和行为构成的封闭体,有对外界的通信接口,外界通过接口与对象交互作用。一个非常形象的例子是电视机,电视机有很多部件组成,可以实现接收电视信号、发送电视画面等许多功能。它与外界的接口就是设置在它表面的一系列按钮或遥控器。
面向对象技术最有用的4个特性是:抽象(abstraction),封装(encapsulation),继承(inheritance)和多态(polymorphism)。
抽象:就是舍去事物的非本质的、非共同的特性,抽取共性和本质特征的过程,将相同特征的事物对象(objects)个体组成为类(class)。例如在医院信息系统中,患者是一个类,医生也可以成为一个类。这就是抽象。有些不同的事物具有某些相同的属性和行为,把这些相同的属性和行为提取出来,组成一个新的类,比如患者和医生在具有姓名、性别这意义上来说是相同的,我们可以将之抽象为个人这个类。
继承:上述患者和医生的例子中,个人这个类是从患者、医生的共同属性和行为抽象类的继承,其中Person 类是Patient 类和Doctor类的父类出来的。我们可以将患者类和医生类设计称为个人这个类的派生类,或者称为子类。而个人类则是患者类和医生类的父类。
所谓继承就是子类自动共享父类的所有属性和行为的机制。继承意味着子类自动拥有和隐含得到父类的属性和行为,父类已经定义的属性和行为在子类中不再需要重新定义。
封装:封装就是把对象的属性和行为结合成一个独立的基本单位。这有两方面的含义,一是属性和行为的结合,强调属性和行为的一体化,二者不可分割;二是信息屏蔽,尽可能屏蔽对象无需为外界所知道的属性和行为的细节,形成一个对外屏障,而仅仅向外界提供有限的接口。
多态:多态的意义就是一个名字具有多个语义。比如生活中我们说打开门窗,打开礼物,打开书本,都用了同一个动词“打开”,但是它在不同的场合有不同的语义,我们不用担心这不同的语义会被误解。在面向对象的软件技术中,在具有继承关系的对象或类中,子类继承父类的某个行为,如果子类的行为表现还有它自身的特点,表现形式不尽相同,那么这个行为具有多态性。支持多态是面向对象程序设计语言的一个基本特征。
对象和类的发现:一般说来,从需求分析中首先找到那些名词(包括人、地点、物品、抽象名词等)。比如我们说“医生需要为患者增添一条血压测量的记录”,这里医生、患者和血压记录都是名词。我们可以据此定义三个类,而医生和患者的类已在前面定义过,所以这里只给出血压类(包括患者标识、医生标识、血压的高低值和测量的时间,以及是否高血压的判断方法)。
这个例子中关于血压类的引入,我们同时也引入了患者标识和医生标识的概念,用这个标识我们可以方便地找到是哪个医生为哪个患者作的该次血压测量。这在数据库中就是表和表之间的关系。通常,对象分析中的一个类,就是将来数据库设计中的一个表。类名就对应于表名,属性就对应于表中的列。一次测量的结果对应于表中一条记录。
通常对每个对象定义一个类,用符号来表示,但需要作适当调整。例如:
(1)分拆:某类的属性或行为不适用于该类的全部对象,例如汽车类,乘客数量属性适用于客车,不适用于货车,这就需要在汽车类下拆分出客车类和货车类。
(2)归并:两类的属性和行为完全相同时,如书籍和计算器是不同的类,但是在商店销售系统中,其属性和行为完全相同,可以合并为商品类。
(3)结构:两类的属性和行为相似,这些类之间或多或少存在某种联系。对于相同属性和方法较多的类,建立继承结构;对于类间具有相同事物对象的,建立整体-部分结构,如汽车和飞机两个类对象,都有发动机,可建立发动机类。
类对象的命名:类名称应能描述类中所有对象的基本特征。
3.5.5数据库工具和数据库设计
现在占市场统治地位的数据库管理系统有Oracle,Sybase,MS SQL,MySQL,Access等等。这些数据库工具经过了无数人的多年开发和应用,已经相当的成熟和完善。应用软件的数据库设计就是使用这些数据库工具设计的。医学信息数据库所要存储、处理的信息量是非常巨大的,而查询又要求准确而迅速,因此选用数据库工具是十分重要的。目前多数的医学数据库采用Oracle、Sybase 或MS SQL 作为其管理系统。无论采用哪种数据库工具,尽管它们在使用方法、命令上有所差别,但是在建表、查询等主要功能的应用上大同小异。
数据库设计的前提是对于系统需求有非常透彻的理解。多数软件系统的开发经验告诉我们,一个好的数据库设计是软件系统成功的一半。当我们对于系统对象分析成熟后,数据库中需要的表也就相当明确了。尽管后续还会有一些调整,但是大的框架,基本结构已经齐备。如前节所述,一个类可以对应数据库中的一个表,类中的属性对应于表中的列,一条数据对应于表中一行。
类,也即数据库中的表的设置是数据库设计的最重要环节。设置过程可以是从大到小、从外向内和从小到大、由内而外的反复完善的过程。一个好数据库的构建不但需要对系统的透彻理解,而且需要丰富的经验,而经验只能通过不断的实践和总结才能获得。
为了实现快捷查找,数据库中往往对一个表内的某列定为此表的索引。如果需要,我们也可以定义若干个列为此表的索引。如果一列索引被单独引用,那么这个列的数据必须是没有相同的。举例说,个人身份信息表的姓名、年龄、性别等显然会有大量是相同,而只有身份证号码是满足惟一性的,因而身份证号码可以被定义为索引。人们往往在表中定义一个被称为序号ID 的索引列,ID 的数值是自动增加的,因而也就不会有相同的值出现。这个序号列的引入,也就保证了表中不会有完全相同的两条记录。所有数据库工具都有这个约束条件,即一个表中,不能有两条记录完全相同。
关于数据库设计的硬件环境、安全等方面的考虑已在本书其他部分论及,此处不再赘述。