专业咨询
致力推进中国医疗卫生信息化

【吴坤专栏】如何开发高性能医疗信息系统(程序设计篇之四)

【编者按】

医疗信息化建设最主要的任务是规划、设计、开发以及部署医疗信息系统。如何开发设计性能良好的医疗信息系统,对于提高医院临床科室的工作效率和医疗信息化工作水平而言至关重要。

在本系列文章中,笔者将围绕“如何开发性能良好的医疗系统软件”这一主题,并结合自身工作经历,分别从软件系统架构设计、程序开发设计、数据库设计开发、项目管理、典型案例等几个方面分享和总结相关经验和教训。 

来源:HIT专家网   作者:华中科技大学同济医学院附属同济医院吴坤

接上篇:【吴坤专栏】如何开发高性能医疗信息系统(程序设计篇之三)

上一篇文章介绍了结构型设计模式在医疗软件开发中的应用,本文将对“行为型设计模式”在医疗软件开发中的应用作相应介绍。

什么是行为型设计模式?行为型设计模式解决何种问题?行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。

行为型模式分为:类行为模式和对象行为模式,前者采用继承机制在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。

行为型设计模式包括:模板方法、策略、命令、责任链、状态、观察者、中介者、迭代器、访问者、备忘录、解释器等11种设计模式。

模板方法模式

在软件开发时,经常会遇到这样的业务流程,以患者就医为例,患者到医院办理业务一般都会经历:挂号、接诊、医疗业务。只是不同患者的业务流程不同,有的是就诊、开药、取药,有的是执行检查检验,有的是退费退药等。但是,不同的流程都是遵循了一个统一的模板,即挂号、接诊和后序医疗业务,挂号的接诊流程对于所有患者都是一样的。模板方法模式就是用来解决类似问题的。

1.模板方法(Template Method)模式的定义:定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以在不改变该算法结构的情况下重定义该算法的某些特定步骤。它是一种类行为型模式。

2.模板方法模式结构图

从模板方法模式的结构图中,可以看出模板方法设计模式是通过封装不变部分,拓展可变部门来实现。

3.模板方法模式的优点

  • 不变部分的算法内容封装在父类,可变部分算法内容由子类通过继承来实现,便于子类继续进行拓展。例如子类可以将可变部分继续划分为不变部分和可变部分,进行下一层模板方法设计。
  • 不变部分内容封装在父类中,可以实现代码复用。
  • 可变部分由子类实现,子类可以根据需要增加相应功能,符合开闭原则。

4.模板方法模式的缺点

  • 每一个不同的业务实现,都需要设计一个子类,会导致系统中类的数量增加,系统变得冗杂。
  • 子类实现父类中的抽象方向,子类执行方法的结果可能会对父类造成影响,导致子类对父类的反向控制。

5.模板方法设计模式的应用场景

(1)算法的整体步骤很固定,但其中个别部分易变时,这时候可以使用模板方法模式,将容易变的部分抽象出来,供子类实现。

(2)当多个子类存在公共的行为时,可以将其提取出来并集中到一个公共父类中,以避免代码重复。首先,要识别现有代码中的不同之处,并且将不同之处分离为新的操作。最后,用一个调用这些新的操作的模板方法来替换这些不同的代码。

(3)当需要控制子类的扩展时,模板方法只在特定点调用钩子操作,这样就只允许在这些点进行扩展。

策略模式

现实生活中我们会遇到这样的场景,在缴纳费用时,可以使用现金、银联卡、支付宝、微信、打折减免等方式来支付;在药品领取时,可以是住院用药、出院带药、院外买药等。这些场景的共同之处就是,实现一个目标,有多种策略可供选择。软件设计中,策略模式就是用来解决此类问题的。

1.策略模式定义

策略模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。

2.策略模式结构图

从结构图中可以看出,策略模式通过定义一个抽象策略类,然后将各种具体的策略算法实现封装在子类中。

3.策略模式的优点

(1)开发程序时多重条件判断代码不易维护,而使用策略模式可以避免使用多重条件判断代码。

(2)策略模式提供了一系列的可供重用的算法族,恰当使用继承可以把算法族的公共代码转移到父类里面,从而避免重复代码。

(3)策略模式可以提供相同行为的不同实现,客户可以根据不同时间或空间要求选择不同的。

(4)策略模式提供了对开闭原则的完美支持,可以在不修改原代码的情况下,灵活增加新算法。

(5)策略模式把算法的使用放到环境类中,而算法的实现移到具体策略类中,实现了二者的分离。

4.策略模式的缺点

  • 客户端必须理解所有策略算法的区别,以便适时选择恰当的算法类。
  • 策略模式造成很多的策略类。

5.策略模式的应用场景

(1)一个系统需要动态地在几种算法中选择一种时,可将每个算法封装到策略类中。

(2)一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现,可将每个条件分支移入它们各自的策略类中以代替这些条件语句。

(3)系统中各算法彼此完全独立,且要求对客户隐藏具体算法的实现细节。

(4)系统要求使用算法的客户不应该知道其操作的数据时,可使用策略模式来隐藏与算法相关的数据结构。

(5)多个类只区别在表现行为不同,可以使用策略模式,在运行时动态选择具体要执行的行为。

命令模式

在软件开发时,常常出现这样的情况,“方法的调用请求者”和“方法的实现者”存在紧密的耦合关系,方法调用者需要通过方法的实现者才能实现对方法的调用。“命令模式”则是用来应对此类问题。

1.命令模式的定义

将一个请求封装为一个对象,使发出请求和执行请求两者分割开。这样两者之间通过命令对象进行沟通,方便将命令对象进行储存、传递、调用、增加与管理。

2.命令模式结构图

调用者将具体命令发送给命令对象,命令对象再调用具体的命令接受者来完成命令的行为动作。

3.命令模式的优点

  • 降低系统的耦合度,命令模式能将调用操作的对象与实现该操作的对象解耦。
  • 增加或删除命令非常方便。采用命令模式增加与删除命令不会影响其他类,它满足“开闭原则”,扩展比较灵活。
  • 可以实现宏命令。命令模式可以与组合模式结合,将多个命令装配成一个组合命令,即宏命令。
  • 方便实现撤销和恢复操作。命令模式可以与后面介绍的备忘录模式结合,实现命令的撤销与恢复。

4.命令模式的缺点

可能产生大量具体命令类。因为针对每一个具体操作都需要设计一个具体命令类,这将增加系统的复杂性。

5.命令模式的应用场景

(1)当系统需要将请求调用者与请求接收者解耦时,命令模式使得调用者和接收者不直接交互。

(2)当系统需要随机请求命令或经常增加或删除命令时,命令模式比较方便实现这些功能。

(3)当系统需要执行一组操作时,命令模式可以定义宏命令来实现该功能。

(4)当系统需要支持命令的撤销操作和恢复操作时,可以将命令对象存储起来,采用备忘录模式来实现。

责任链模式

在日常生活中,经常会遇到这样的场景,一件事情需要经由不同的人来完成。例如,一条医嘱的执行可能需要经由主治医师、主任医师等不同级别医生来完成。主治医师开立医嘱,主任医生进行审核。责任链模式正是用来应对这一应用场景。

1.责任链模式定义

为了避免请求发送者与多个请求处理者耦合在一起,将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。

2.责任链模式的优点

(1)降低了对象之间的耦合度。该模式使得一个对象无须知道到底是哪一个对象处理其请求以及链的结构,发送者和接收者也无须拥有对方的明确信息。

(2)增强了系统的可扩展性。可以根据需要增加新的请求处理类,满足开闭原则。

(3)增强了给对象指派职责的灵活性。当工作流程发生变化,可以动态地改变链内的成员或者调动它们的次序,也可动态地新增或者删除责任。

(4)责任链简化了对象之间的连接。每个对象只需保持一个指向其后继者的引用,不需保持其他所有处理者的引用,这避免了使用众多的if 或者if···else 语句。

(5)责任分担。每个类只需要处理自己该处理的工作,不该处理的传递给下一个对象完成,明确各类的责任范围,符合类的单一职责原则。

3.责任链模式的缺点

(1)不能保证每个请求一定被处理。由于一个请求没有明确的接收者,所以不能保证它一定会被处理,该请求可能一直传到链的末端都得不到处理。

(2)对比较长的职责链,请求的处理可能涉及多个处理对象,系统性能将受到一定影响。

(3)职责链建立的合理性要靠客户端来保证,增加了客户端的复杂性,可能会由于职责链的错误设置而导致系统出错,如可能会造成循环调用。

4.责任链模式的应用场景

(1)有多个对象可以处理一个请求,哪个对象处理该请求由运行时刻自动确定。

(2)可动态指定一组对象处理请求,或添加新的处理者。

(3)在不明确指定请求处理者的情况下,向多个处理者中的一个提交请求。

状态模式

在软件开发过程中,应用程序中的有些对象可能会根据不同的情况做出不同的行为,我们把这种对象称为“有状态的对象”,而把影响对象行为的一个或多个动态变化的属性称为“状态”。当有状态的对象与外部事件产生互动时,其内部状态会发生改变,从而使得其行为也随之发生改变。“状态模式”正是用来处理这样的问题。

1.状态模式的定义

对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。

2.状态模式结构图

状态模式把受环境改变的对象行为包装在不同的状态对象里,其意图是让一个对象在其内部状态改变的时候,其行为也随之改变。结构图如下:

3.状态模式的优点

  • 状态模式将与特定状态相关的行为局部化到一个状态中,并且将不同状态的行为分割开来,满足“单一职责原则”。
  • 减少对象间的相互依赖。将不同的状态引入独立的对象中会使得状态转换变得更加明确,且减少对象间的相互依赖。
  • 有利于程序的扩展。通过定义新的子类很容易地增加新的状态和转换。

4.状态模式的缺点

  • 状态模式的使用必然会增加系统的类与对象的个数。
  • 状态模式的结构与实现都较为复杂,如果使用不当会导致程序结构和代码的混乱。

5.状态模式的应用场景

(1)当一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为时,就可以考虑使用状态模式。

(2)一个操作中含有庞大的分支结构,并且这些分支决定于对象的状态时。

观察者模式

在软件系统设计时,许多对象并不是独立存在的,其中一个对象的行为发生改变可能会导致一个或者多个其他对象的行为也发生改变。例如检查检验系统完成检验后,需要通知HIS系统、报告系统等。

1.观察者模式的定义

指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作“发布-订阅模式”、“模型-视图模式”,它是对象行为型模式。

2.观察者模式结构图

3.观察者模式的优点

  • 降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。
  • 目标与观察者之间建立了一套触发机制。

4.观察者模式的缺点

  • 目标与观察者之间的依赖关系并没有完全解除,而且有可能出现循环引用。
  • 当观察者对象很多时,通知的发布会花费很多时间,影响程序的效率。

5.观察者模式应用场景

(1)对象间存在一对多关系,一个对象的状态发生改变会影响其他对象。

(2)当一个抽象模型有两个方面,其中一个方面依赖于另一方面时,可将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。

中介者模式

在现实生活和软件系统中,经常存在着各个对象之间的错综复杂的关系,需要一个中介对象来处理各对象之间的关系交互,以消除对象之间形成的网络关系结构。中介者模式正是用来应对这一问题的。

1.中介者模式的定义

定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。中介者模式又叫调停模式,它是迪米特法则的典型应用。

2.中介者模式的优点

  • 降低了对象之间的耦合性,使得对象易于独立地被复用。
  • 将对象间的一对多关联转变为一对一的关联,提高系统的灵活性,使得系统易于维护和扩展。

3.中介者模式的缺点

当同事类太多时,中介者的职责将很大,它会变得复杂而庞大,以至于系统难以维护。

4.中介者模式的应用场景

(1)对象之间存在复杂的网状结构关系而导致依赖关系混乱且难以复用。

(2)想创建一个运行于多个类之间的对象,又不想生成新的子类。

迭代器模式

在软件设计时,会遇到需要访问聚合对象中的所有元素的情况,例如链表结构中数据元素的遍历访问。而将聚合元素对象的创建和访问都封装在一个类中,不利于软件程序的拓展。迭代器模式用来解决此类问题。

1.迭代器模式的定义

提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。

2.迭代器模式的优点

  • 访问一个聚合对象的内容而无须暴露它的内部表示。
  • 遍历任务交由迭代器完成,这简化了聚合类。
  • 它支持以不同方式遍历一个聚合,甚至可以自定义迭代器的子类以支持新的遍历。
  • 增加新的聚合类和迭代器类都很方便,无须修改原有代码。
  • 封装性良好,为遍历不同的聚合结构提供一个统一的接口。

3.迭代器模式的缺点

增加了类的个数,这在一定程度上增加了系统的复杂性。

4.迭代器模式的应用场景

(1)需要为聚合对象提供多种遍历方式时。

(2)需要为遍历不同的聚合结构提供一个统一的接口时。

(3)访问一个聚合对象的内容而无须暴露其内部细节的表示时。

访问者模式

医生开的处方单中包含多种药元素,査看它的划价员和药房工作人员对它的处理方式也不同,划价员根据处方单上面的药品名和数量进行划价,药房工作人员根据处方单的内容进行抓药。“访问者”模式正是用来处理这些数据元素相对稳定、访问方式多种多样的数据结构问题。

1.访问者模式定义

将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新操作,为数据结构中的每个元素提供多种访问方式。它将对数据操作与数据结构进行分离,是行为类模式中最复杂的一种模式。

2.访问者模式结构图

从结构图中可以看出,“访问者模式”把处理方法从数据结构中分离出来,并可以根据需要增加新的处理方法,且不用修改原来的程序代码与数据结构,这提高了程序的扩展性和灵活性。

3.访问者模式的优点

  • 扩展性好。能够在不修改对象结构中的元素的情况下,为对象结构中的元素添加新功能。
  • 复用性好。可以通过访问者来定义整个对象结构通用的功能,从而提高系统的复用程度。
  • 灵活性好。访问者模式将数据结构与作用于结构上的操作解耦,使得操作集合可相对自由地演化,而不影响系统的数据结构。
  • 符合单一职责原则。访问者模式把相关的行为封装在一起,构成一个访问者,使每一个访问者的功能都比较单一。

4.访问者模式的缺点

  • 增加新的元素类很困难。在访问者模式中,每增加一个新的元素类,都要在每一个具体访问者类中增加相应的具体操作,这违背了“开闭原则”。
  • 破坏封装。访问者模式中具体元素对访问者公布细节,这破坏了对象的封装性。
  • 违反了依赖倒置原则。访问者模式依赖了具体类,而没有依赖抽象类

5.访问者模式的应用场景

(1)对象结构相对稳定,但其操作算法经常变化的程序。

(2)对象结构中的对象需要提供多种不同且不相关的操作,而且要避免让这些操作的变化影响对象的结构。

(3)对象结构包含很多类型的对象,希望对这些对象实施一些依赖其具体类型的操作。

备忘录模式

1.备忘录模式定义

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态。

2.备忘录模式结构图

备忘录模式的核心是设计备忘录类以及用于管理备忘录的管理者类,记录一个对象的内部状态,当用户后悔时能撤销当前操作,使数据恢复到原先的状态。

3.备忘录模式的优点

(1)提供了一种可以恢复状态的机制。当用户需要时能够比较方便地将数据恢复到某个历史的状态。

(2)实现了内部状态的封装。除了创建它的发起人之外,其他对象都不能够访问这些状态信息。

(3)简化了发起人类。发起人不需要管理和保存其内部状态的各个备份,所有状态信息都保存在备忘录中,并由管理者进行管理,这符合单一职责原则。

4.备忘录模式的缺点

资源消耗大。如果要保存的内部状态信息过多或者特别频繁,将会占用比较大的内存资源。

5.备忘录模式的应用场景

(1)需要保存恢复数据的场景,如玩游戏时的中间结果的存档功能。

(2)需要提供一个可回滚操作的场景,如Word、记事本、Photoshop,Eclipse 等软件在编辑时按Ctrl+Z 组合键,还有数据库中事务操作。

解释器模式

1.解释器模式定义

给分析对象定义一个语言,并定义该语言的文法表示,再设计一个解析器来解释语言中的句子。也就是说,用编译语言的方式来分析应用中的实例。

2.解释器模式结构图

终结表达式类和非终结表达式类,是抽象表达式的子类。终结表达式用来实现文法中与终结符相关的操作,文法中的每一个终结符都有一个具体终结表达式与之相对应。非终结表达式用来实现文法中与非终结符相关的操作,文法中的每条规则都对应于一个非终结符表达式。

3.解释器模式的优点

  • 扩展性好。由于在解释器模式中使用类来表示语言的文法规则,因此可以通过继承等机制来改变或扩展文法。
  • 容易实现。在语法树中的每个表达式节点类都是相似的,所以实现其文法较为容易。

4.解释器模式的缺点

  • 执行效率较低。解释器模式中通常使用大量的循环和递归调用,当要解释的句子较复杂时,其运行速度很慢,且代码的调试过程也比较麻烦。
  • 会引起类膨胀。解释器模式中的每条规则至少需要定义一个类,当包含的文法规则很多时,类的个数将急剧增加,导致系统难以管理与维护。
  • 可应用的场景比较少。在软件开发中,需要定义语言文法的应用实例非常少,所以这种模式很少被使用到。

5.解释器模式的应用场景

(1)语言的文法较为简单,且执行效率不是关键问题时。

(2)问题重复出现,且可以用一种简单的语言来进行表达时。

(3)一个语言需要解释执行,并且语言中的句子可以表示为一个抽象语法树的时候,如XML文档解释。

行为型设计模式在医疗软件设计中的应用

医生开立的医嘱,例如检查、检验医嘱,对应着不同状态:预约、执行、退费等。不同状态对应着不同的执行过程,医嘱为预约状态时,需要向检查预约登记系统发送通知消息;医嘱为执行状态时,从预交金扣除相应费用;医嘱为退费状态时,向收费系统发送通知消息。如下图所示:

根据医嘱的不同状态,将相应的行为工作封装到不同的状态,医嘱状态发生变化时,调用相应的状态类执行相应的动作行为即可。后序当有新的状态时,继承新增状态类,将相应的动作行为封装到新增类中即可。

【作者简介】

吴坤,计算机专业硕士,华中科技大学同济医学院附属同济医院信息中心软件工程师。专业计算机程序员,医疗信息技术推广者,积极参与社会活动,热衷于以信息技术提高医疗行业服务质量和改善患者就医体验。

小助手二维码

想加入HIT专家网专业交流群吗?请添加“HIT专家网小助手微信好友

(请务必注明姓名、单位名称、职务、主管技术或产品领域等实名信息)

【责任编辑:谭啸】

赞(9)

评论 抢沙发

评论前必须登录!

 

未经允许不得转载:HIT专家网 » 【吴坤专栏】如何开发高性能医疗信息系统(程序设计篇之四)
分享到: 更多 (0)