软件设计模式实现一个医院系统的部分功能

现假设要实现一个医院系统的部分功能利用软件设计模式

医院系统问题

病人就诊:病人看病需要经过挂号(选择诊疗科目、选择医生),医生确诊,付费,医生治疗,结束治疗5个步骤,不同的步骤,不同的医院有不同的做法,请用模板方法模式抽象出这个病人就诊步骤,并能方便扩展。

医生确诊需要开病例单,病人根据病历单的费用进行付费。病历单包括”基础诊疗费”和其它药物或治疗方法的费用,请用装饰器模式实现这个病历单,从而方便扩展不同的药物或治疗方法,并能够得到总费用,便于扩展。

医院的部门结构往往是一个树状结构,而医生属于某个科室如图1-1所示,请用组合模式,实现医院结构,并能将这个组合模式应用到病人挂号处,方便的得到某种诊疗科目的所有医生,供病人选择。

image.png

图 1-1 医院组织结构分布图

1.1 问题分析

问题分析就从题目内容展开分析,首先要做的就是基于问题的初步定义,对问题进行进一步的分解,这个分解可以是目标本身的分解,也可以是问题可能产生原因的分解。

1.1.1看病流程

根据题干中要求的去医院看病流程最重要有5个实际流程如图2-1所示,这里看病流程,基本满足普通医院及综合医院的流程需求。但还需要考虑到诊所看病的流程也满足这5个步骤。它用于描述看病步骤之间执行的先后顺序。图中的每个步骤结点可以用来表示一个完整的看病步骤,乃至整个看病流程,看病步骤结点间的有向边则表示两个步骤之间存在的偏序或者前驱关系。挂后步骤可以看着是医生确诊步骤的直接前驱步骤,而称医生确诊步骤是挂号步骤的直接后驱步骤。在图2-1中存在者如下的看病步骤关系:a -> b, b -> c, c -> d, d -> e或表示为:P={a,b,c,d,e}={(a,b),(b,c),(c,d),(d,e)}。

通常,一个完整的医院看病流程由以上5个步骤组成,每个看病步骤完成特定的任务,它们在进行时,都需要按照一定的先后次序顺序执行,仅当前一个步骤执行完成后,才执行后一个看病步骤。

image.png

图 2-1 医院看病关键流程

1.1.2挂号选择

挂号步骤中也包含了一定的挂号先后次序顺序如图2-2所示。需要注意的是在挂号步骤,是需要展示医院组织关系图如图1-1,通过组织人员关系图来选择需要挂号医生。如果未选择需要进行挂号的医生,那挂号步骤将不能执行完成,随着挂号失败对应的看病流程已将无法按照顺序执行下去。

image.png

图 2-2 医院挂号流程

1.1.3 结账计算

在进行病例结账步骤,必须要付费的直接前驱医生确诊步骤完成后才能进行付费详细执行顺序如图2-3所示。在医生确诊过程中会对病例进行修改,修改的内容主要是药品信息,病例上的信息都是为后面的付费步骤提供数据基础。付费需要先计算病例中药品合计金额,只有计算出正确金额,才可以进行后面操作。

image.png

图 2-3 医生确诊与付费流程

1.2 设计思路

1.2.1看病步骤

通过对图2-1看病步骤的分析,每个看病步骤完成特定的任务,它们在进行时,都需要按照一定的先后次序顺序执行,仅当前一个步骤执行完成后,才执行后一个看病步骤。我们将主要的5个看病步骤抽象成一个模板方法。每个对应的步骤进行方法抽象,具体看病步骤的实现要根据实际医院进行具体的步骤实现。如诊所基本上没有挂号这个流程,诊所在实现挂号可以进行空实现。而普通医院可以实现选择指定医生进行挂号步骤。根据看病步骤为先后次序顺序执行,可以将看病步骤在一个方法中定义一个算法的骨架, 而将一些步骤延迟到具体的医院子类中. 模板方法使得具体医院子类可以在不改变算法结构的情况下, 重新定义算法中的某些步骤UML类设计见图2-4所示,看病流程如图2-7所示

image.png

图 2-4 看病流程框架UML

1.2.2医生结构

医院的医生组织结构,在组织模式上类似树的层次结构。允许你将对象组合成树形结构来表现"整体/部分"层次结构。组合能让客户以一致的方式处理个别对象以及对象组合。将对象组合成树形结构来表示”整体/部分”层次关系,允许用户以相同的方式处理单独对象和组合对象,组件(Component)类是组合类(Composite)和叶子类(Leaf)的父类,可以把组合类看成是树的中间节点。组合模式只适用于结构已知的树形结构,复杂结构不采用组合模式。可以将医院的各个科室组织为组合类,而每个科室的医生可以组织成叶子类。将科室组合类与医生叶子类组成一个树型结构,完整展示医院人员组织的结构UML类图如2-5所示。

image.png

图 2-5 医院组织人员框架UML

image.png

图 2-6 病例报告框架UML

1.2.3病例实现

病例主要是记录医生开药的一些药品信息,但是在记录药品时,没办法提前预知需要的药品名称品类和数量,所有没办法进行案例的价格合计。随着药品数量不确定性,可以将基础的病例进行装饰得到不同药品的装饰器。

装饰者(Decorator)和具体组件(ConcreteComponent)都继承自组件(Component),具体组件的方法实现不需要依赖于其它对象,而装饰者组合了一个组件,这样它可以装饰其它装饰者或者具体组件。所谓装饰,就是把这个装饰者套在被装饰者之上,从而动态扩展被装饰者的功能。装饰者的方法有一部分是自己的,这属于它的功能,然后调用被装饰者的方法实现,从而也保留了被装饰者的功能。

把病例中的药品,检查共同抽象为一个组件,而具体的药品信息,检查项目就为装饰者,在进行药品添加时就相当于给基础的病例进行一次次的装饰.最后得到完整病例具体UML类图如图2-6所示。

1.3 编码与测试

1.3.1框架代码:
  1. 按住Ctrl点击查看Git仓库:设计模式期末1框架代码
1.3.2测试结果:

image.png

image.png

1.4 总结

在这个题目中在使用对应的设计模式开发过程中,对应问题再使用设计模式实现,跟实际业务需求有差别。设计模式是再软件开发中的一些问题解决方案,该方案不一定是最好的办法。但是这个方案是由众多的失败经验总结而得到的。

学习设计模式,使我再实际开发中的由原来的面向类开发逐渐熟悉使用面向接口开发。使自己的代码更容易进行扩展与理解。

再使用设计模式是为了降低开发代码的冗余,为了重用代码、让代码更容易被他人理解、保证代码可靠性。设计模式再软件工程开发中起到重要的基石作用,不是所有的问题都可以用设计模式来解决,设计模式针对平时出现在现实生活中都又之来对应,每种模式都描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是设计模式能被广泛应用的原因。

image.png

图 2-7 患者选择医院看病流程图