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

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

【编者按】

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

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

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

接上篇:如何开发高性能医疗信息系统(系统架构篇)

在软件产品生成过程中,程序设计属于产品的制造过程,程序设计和开发的好坏直接关系着产品质量好坏。这类似于工业化生产过程中的车间产品制造加工过程,工人师傅的操作、技能以及生产流程等具体细节,都直接影响着产品质量。

在当前“互联网+”背景下,BAT等互联网公司掌握着最先进的软件生产技术,这些公司业务软件系统承受着巨大业务量,比如在每年“双11”期间,淘宝网业务访问并发量数以亿计,远远超过了高性能,甚至达到了超性能。所以,本系列文章在撰写过程中,参考了互联网公司的相关技术。笔者希望医疗软件公司和医疗机构在技术上能向互联网公司看齐,所开发的医疗业务软件能达到互联网应用程序水平,兼具高性能和良好的用户体验。

在软件设计时,特别是对于大规模企业级软件的设计,遵循既定的设计法则,往往总能起到意想不到的效果。因此,软件工程师在开发设计程序时,注重规范和法则往往是开发高质量高性能软件的基础和保障,本篇文章主要探讨软件设计六大法则的应用(由于笔者日常工作主要基于J2EE相关技术开发医疗软件系统,因此本系列文章很多内容主要基于Java面向对象设计)。

单一职责原则

简单来讲,单一职责原则就是一个类只负责一项职责功能。如果一个类T负责实现两个不同的功能P1和P2,当P1需求发生变化而要修改类T时,有可能导致功能P2出现故障,而避免出现这一问题的方法就是遵循单一职责原则。

但在遵循单一职责法则时,会存在功能扩散问题。比如,原先类T实现功能P,后来出现了新的需求变动,功能P被细分为P1和P2,类T也就要随之划分为T1和T2,此时通过修改类T的程序代码来实现这一变化很复杂。在功能不断拓散到无法控制时,就需要对程序进行代码重构。

总体而言,遵循单一职责设计程序,能带来三点益处:

一是明显降低程序类的复杂度,一个类只负责一项职责,其逻辑要比负责多项职责功能简单得多;

二是提高类的可读性,提高系统的可维护性;

三是降低变更引起的风险。如果单一职责原则遵守得好,当修改某一功能时,可显著降低对其他功能的影响。

氏替换原则

里氏替换原则的定义:所有引用基类的地方必须能透明地引用子类对象。

从定义可看出,里氏替换原则解决的是子类父类继承的问题。医生类T1实现开医嘱功能P1,现在需要对功能P1进行拓展,比如有的医生除了需要“开立医嘱”外,还需要“撰写检查报告”。拓展后的功能P由“开立医嘱”P1功能和“撰写检查报告”功能P2组成,拓展所得的新功能P由医生类T1的子类T2来实现。子类T2在实现新功能P的同时,可能会导致原有功能P1出现问题。

要解决这一问题,就需要遵循里氏替换法则,在设计实现子类T2时,通过新增功能“撰写检查报告”,而不是直接拓展父类T1中“开立医嘱”功能来实现。类T2中继承父类T1中“开立医嘱”功能方法,并新增“撰写检查报告”功能方法,父类中原有“开立医嘱”功能方法并没有发生任何变化(直接继承)。

过度使用继承会带来很多问题,比如带来程序侵入性,导致程序的可移植性降低,增加对象间的耦合性。如果一个类被其他的类所继承,当这个类需要修改时,必须考虑到所有的子类,而且修改父类后,所有涉及到子类的功能都有可能发生问题。对于父类中已经实现好的方法,实际上是一种规范和契约,虽然不强制要求之类严格遵循(子类可重写这些方法),但是如果子类对父类中已实现的方法随意进行修改,就可能造成整个继承体系紊乱。

避免上述问题的方法就是遵循里氏替换法则,当使用继承时,除添加新的方法完成新增功能外,尽量不要重写父类的方法,也尽量不要重载父类的方法。即子类可以扩展父类的功能,但不能改变父类原有的功能。

里氏替换原则包含以下4层含义

(1)子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。

(2)子类中可以增加自己特有的方法。

(3)当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。例如父类方法参数为INT(数据类型),子类方法参数设置为FLOAT(浮点型数据类型)或者DOUBLE类型(双精度浮点型)。

(4)当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。比如,父类中方法返回FLOAT类型值,子类中返回FLOAT、INT类型值,而不能返回DOUBLE类型值。

在软件开发时遵循里氏替换法则,可以降低程序出错的概率。

依赖倒转原则

依赖倒转原则的定义:高层模块不应该依赖低层模块,二者都应该依赖抽象;抽象不应该依赖细节;细节应该依赖抽象。

依赖倒转最主要的思想是面向抽象编程,而不是面向实现编程。这是因为相对于细节的多变性,抽象的东西要稳定得多。以抽象为基础搭建起来的架构比以细节为基础搭建起来的架构要稳定的多。在面向对象语言中,抽象通常指接口或者抽象类,细节就是具体的实现类,使用接口或者抽象类的目的是制定好规范和契约,而不去涉及任何具体的操作,把展现细节的任务交给他们的实现类去完成。

在实际程序开发时,一般做到如下几点即可:

(1)每个类尽量提供抽象类或接口,或者两者都有;

(2)变量的声明类型尽量是抽象类或接口;

(3)使用继承时遵循里氏替换原则;

(4)任何一个类尽量不要派生于具体实现类。

比如,在系统内部设计一个支付结算类(Payment),该类包含了一个方法支付费用(Pay()),可以将该类设计成抽象接口,然后通过实现该接口来设计具体的现金支付类、银联卡支付类等。因此,每新增一种支付方式,只需通过实现该接口方法设计一个新的支付方式类即可。

接口隔离原则

接口隔离法则的定义:一个类不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。

接口隔离原则所表达的含义是在程序设计时尽量建立单一接口,不要建立庞大臃肿的接口,尽量细化接口,接口中的方法尽量少。也就是说,要为各个类建立专用的接口,而不要试图建立一个很庞大的接口供所有依赖它的类去实现调用。

比如,医院财务部门存在窗口结算员、账务审核人员、会计做账人员等工作人员,相应有结算员类、财务审核员类、会计员类。其中,结算员类有收费、退费、查看费用明细等功能,财务审核员类有对账、财务审核等功能,会计员类有会计做账功能。在进行程序设计时,应该为每一个类设计专用接口,而不是设计一个综合接口让所有类去实现。

上图实现了将一个庞大的接口变更为3个专用接口,所采用的就是接口隔离原则。在程序设计中,依赖几个专用的接口要比依赖一个综合的接口更灵活。因为接口是设计时对外部设定的“契约”,通过分散定义多个接口,可以预防外来变更的扩散,提高系统的灵活性和可维护性。

迪米特原则

迪米特原则也叫最少知识原则。简单来讲,就是一个类对自己依赖的类“知道”得越少越好。对于被依赖的类,无论逻辑多么复杂,都尽量将逻辑封装在类的内部,对外除了提供的Public方法,不要暴露任何信息。

遵循迪米特原则可以避免与非直接依赖的类通信,降低类之间的耦合性。但如果需要通信,必然要通过一个“中介”类来发生联系。比如,医院不同科室部门员工不能直接通信,需要一个“中介”类实现不同科室部门员工类之间的联系。但是过度遵循迪米特原则,可能会使程序中产生大量“中介”类,导致系统过于复杂。因此,在程序开发时,遵循迪米特法则要反复权衡,既要降低类之间耦合,也要兼顾到程序简洁性。

开闭原则

开闭原则很容易理解:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的程序代码来实现。

在软件的生命周期内,因为变化、升级和维护等原因需要对软件原有代码进行修改时,可能引入错误带来BUG,也可能需要对整个软件进行代码重构。应对这一问题的方法就是遵循开闭原则。开闭原则是面向对象设计中最基本的原则,用于指导设计开发出稳定灵活的系统。深入对比可以发现,开闭原则与前面几项原则有重合之处。

其实,开闭原则本身就是所有设计原则的基础,其他五项原则或多或少都含有开闭原则的思想。遵循前面五项设计法则,也就间接遵循了开闭原则。前面五项原则最核心的思想就是用抽象构建框架,用实现来扩展细节:单一职责原则告诉我们实现类要职责单一;里氏替换原则告诉我们不要破坏继承体系;依赖倒置原则告诉我们要面向接口编程;接口隔离原则告诉我们在设计接口的时候要精简单一;迪米特法则告诉我们要降低耦合。而开闭原则是总纲,告诉我们要对扩展开放,对修改关闭。

开发设计程序,首先要有指导思想和设计法则,遵循法则做事或许不能完全保证开发出功能完善、性能优越的软件,因为软件系统开发还包括算法、数据库、项目管理等很多方面的因素。但是遵循一定的设计法则,能保证少走弯路。就笔者工作经验而言,医疗系统软件有其自身应用场景,适当遵循设计法则将大有裨益。当然,对于经验丰富的工程师而言,可以根据自身需要灵活运用。

【作者简介】

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

小助手二维码

想加入HIT专家网专业交流群吗?请添加“HIT专家网”小助手微信好友后提交你的申请哦

(请注明姓名、单位名称、职务、主管技术或产品领域,以便有针对性加群)

【责任编辑:孙鹏】

赞(11)

评论 1

评论前必须登录!

 

  1. #1

    非常专业的设计模式介绍,点赞

    Taimur5年前 (2019-08-07)


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