您的位置:首页 > 职场人生

技术支持程序员程序书写规范

2006-09-23 19:49 453 查看
技术支持程序员程序书写规范
编制:李群巍
日期:2002-5-15

一、导言

BSHIS的软件客户化工作是一个庞大的系统工程。客户化工作的好坏,软件质量的好坏直接影响着工程实施和工程进度。为了保证技术支持部程序员编写程序的质量和技术支持的质量,特制定以下技术规范和代码书写注意事项。
此规范是个初稿,在实际应用中,尚需要不断完善和调整。另外,请各序员在实际操作过程中,提出自己的看法和建设性的意见和建议,以使规范不断完善。

二、系统公用模块修改

1、 support.pbl和hispublic.pbl要求各个子系统版本一致

2、 若发现标准版本错误,分类别处理

若是比较简单的错误,很容易修改的,请自行修改,并及时将修改资料交到部门领导,到时候统一提交到质量部,以便及时通报各个技术人员。若是牵涉到很复杂的或者是有很大的业务调整,请提交领导审批后再进行修改。
:如:新增系统公用功能,虽然是可以放在以上两个PBL,但为了不致被覆盖,最好还是自己新建PBL的好。以上PBL中的代码也不要去擅自去调整。

3、请不要将客户化的内容放在support.pbl和hispublic.pbl

4、若一定要对公用模块要进行客户化修改,可从其继承,再作修改

DATAWINDOW有修改的话,请在继承的模块中引用新的从原来的复制下来再进行修改过的DATAWINDOW,而不要直接去修改原来的DATAWINDOW。

三、程序代码编制规范

请参考产品质量部的《程序编制规范.doc》
下面着重讲讲一些经常在工作中出现的不规范的情况和应该注意的地方:

1、 变量命名规范

典型的不规范的情况有:
如:局部变量命名为:integer gl_ksdm
实例变量命名为:integer ll_ksdm
我们命名原则的指定,宗旨是看到这个变量就应该知道是什么变量(全局、局部、实例、共享),是什么类型。良好的变量命名习惯可以使程序阅读起来很轻松,也可提高工作效率和错误的理解导致的工作不便。
变量的类型
对象
类型
前缀
备注
整型数字
Int
I_
界面中右对齐
Long
L_
界面中右对齐
浮点型数字
Double
D_
界面中右对齐
Decimal
Dc_
界面中右对齐
日期
Date
D_
界面中左对齐或居中
格式一般为:
yyyy.mm.dd
Datetime
Dt_
Yyyy.mm.dd hh:mm:ss
Time
T_
HH:MM:SS
类实例
可视
Vu_
非可视
U_
字符串
String
S_
界面中左对齐或居中

结构体
Struct
Str_
布尔型
Boolean
B_
居中
变量的范围:
前缀
含义
G
全局
S
共享
I
实例
L
局部
A
参数
变量命名
变量范围+变量类型+‘_’+变量名称
例:全局的日期为Gd_today,门诊号参数As_mzhm
注:BSHIS2.2公共全局类名:Uo_support::U_supporclass
BSHIS2.2全局参数结构名:Base_info::Base_info
BSHIS2.2窗口数据传输变量结构:S_Exchange::S_Exchange

2、窗口和窗口相关的DATAWINDOW命名规范

一般将窗口相关的DATAWINDOW,具有和窗口相同的前缀。
这样做的好处是:复制模块或者整理和查看程序的时候很容易
如:w_yk_jchz (药库系统的进出汇总模块)
相关的datawindow可命名为 d_yk_jchz
其他相关的模块和DATAWINDOW都命名为包含 _yk_jchz_ 做为前缀的名字
目前存在乱命名的情况,严重的甚至出现同个系统的不同PBL出现名字重复。
有时候程序数据检索错误,就是这个原因导致的,有时候我们还可能花很大的力气去找原因。
如:his2.1系统药房系统中 d_ypxx 就出现过同名异构的DATAWINDOW

3、函数的命名规范

(1)公用全局函数:

GF_XXXX(GF+_+函数名称)

(2)子系统使用的公共函数:

GF_XX_XXXX(GF+_+系统简称+_+函数名称)

(3)窗口函数:

WF_XXXX(WF+_+函数名称)

(4)类成员函数:

Object.XXXX(函数名称)
Object.of_XXXX(被其他对象和模块调用)
Object.uf_XXXX(内部调用)

(5)全局扩展函数:

GE_XXXX(GE+_+函数名称)

(6)局部扩展函数:

LE_XXXX(LE+_+函数名称)

4、数据窗口命名规范

(1)下拉式数据窗口:

DD_XXXX

(2)一般数据窗口:

D_XX_XXXX(D+_+系统简写+_+数据窗口名称)
主要,窗口私用的DATAWINDOW的命名的前缀除 d_ 外 一般和 窗口的名字同
如:d_yk_jchz 属于 w_yk_jchz 模块

5、类的命名规范

U_XXXX(非可视类)
VU_XXXX(可视类)

四、程序修改的原则

1、需求修改的时机

1)错误修正:应尽快更正

2)不得不改的需求:

主要是涉及医院基础流程的东西,如不修改,医院的HIS流程将走不通。对此问题,一般根据医院自身的特色和BSHIS的程序特点,双放协商一种比较好的折中的方法。

3)一般需求(一般性的功能扩充):可改可不改

如:
药库出库处理模块可监控药房是否已确认入库
某个查询模块,要增加几个过滤条件
药库入库、出库单可连续打印

4)尽量用变通的方法解决

如:
有些医院药库本院自制的药品较多,入库要与一般采购入库分开(区分),若放到其他入库中,则许多采购入库的分析模块不能使用。解决:可新增一个供货单位(如:“本院自制”),采用采购入库模块即可。
5)与其他技术人员及时交流
特别是一些比较难查的错误,可先问问别的技术人员是否已经处理过,避免重复劳动。
6)有些较大的流程调整性的修改,一般需要讨论或者和院方进行协商后再进行修改。

2、修改程序的方法和技巧

1)定期对修改过的医院需求和程序作一些整理。

总结出共性的需求和比较普遍的客户化工作,做一些共享模块和公用模块,为下一次需求修改作预备工作。如时间许可,在改程序时应尽量考虑公用性,可以在其他医院或其他系统中比较容易地挂接。
建议每个程序员自己建议一套自己的客户化支持库,可大大提高自己的代码书写速度和质量,并定期与其他程序员进行交流。

2)充分利用面向对象的编程思路

如:HIS22的病区药房发药处理对象(基本医嘱、急诊医嘱、医技用药、出院带药等)就是一个例子。
目前在客户化的时候在此方面比较欠缺。
当然,在设计对象时,应尽量考虑通用性和可移植性。不要使对象内部的处理逻辑太依赖外部的模块代码的数据。
典型的面向对象的应用是各地的医保支持处理代码,可充分利用面向对象的编程技术。

五、客户化规范

1、关于新增客户化PBL

对于医院新增加的功能模块所使用的模块,一般单独放在一个PBL中
新增PBL的命名规范为:
<系统简称>_<医院简称>.pbl
<系统简称>采用系统名称的首字母组成。
<医院简称>采用医院名称的首字母组成。
如浙江妇保的药房系统新增了模块,命名为:yf_zjfb.pbl
也可以命名为 yf_expand.pbl
不得以程序员已经的名字命名PBL
不能在新增的PBL中出现重复的对象,以前老的版本不用的PBL,不要放在程序目录下,避免其他工程人员在编译时将其加入到编译路径中。

2、关于区分中西药库、药房的各个系统

不要中药库(房)一套程序,不要西药库(房)一套程序,病区药房一套程序,导致不必要的代码冗余和后期代码维护的混乱。
只要药库程序一套,药房程序一套就可以了。若有中西的代码区别,在内部程序做处理。
若操作员使用的门诊系统和财务人员使用的有功能上的不同,也不要搞成几套程序,可用系统参数或者其他方法加以控制。

3、关于程序性能

程序写好了后,还需要注意程序的性能,这个特别是对比较大的医院要求特别的苛刻。
下面是程序在性能方面的一般解决方法和注意事项:

(1)注意控制数据库更新事物

不更新数据时保持 SQLCA.AUTOCOMMIT 为 TRUE,避免当前事务一直处于激活状态,影响别的事务。就是要写 gf_begin_transaction() 和 gf_commit_transaction()来处理事务。
按经常被检索的单元物理排序。

(2)合理和充分使用表的物理索引(即簇索引)

如:ZY_BQYZ表,按SRKS字段进行批量处理的机会比较多,所以在此上建立物理所以可减少锁表,同时可加快检索速度(检索物理索引时比逻辑索引快的多)。因为 Sql Server 需一个一个数据页的访问,建立Clustered 索引可减少切换页面的时耗,若执行更新数据语句,也可减少锁表。

(3)尽量让事务处理的时间比较短

缩短一个事务更新数据的时延,若在事务中有运算,应先在本地全部做好,再用 DataWindow 一次性更新。
如:住院系统中病人性质转换。

(4)处理好循环嵌套,应该将大循环放在里面。

(5)关注网卡的性能,很影响数据检索的速度

(6)避免使用游标,多用 DataWindow 或 DataStore,先批量查询必要数据,在进行本地特殊处理

Cursor 在执行 Fetch 时始终与服务器保持通信,若在 Fetch 语句中嵌入查询或其他比较耗时的语句,将导致整个查询很慢。替代的办法是:先用 DataWindow 一次性检索数据到本地,在用循环替代 Fetch。
如:住院个人日结、汇总报表优化属于这一类。

(7)对历史数据执行数据转储,避免数据过于集中

如:将 ZY_BQYZ 表中出院病人的医嘱转到 ZY_BQYZ_CY (历史医嘱表)中,可保持 ZY_BQYZ 表规模相对较稳定,保证业务速度。

(8)对于比较大的统计查询,应该先将结果保存起来

可象院长查询系统一样,一些历史性且不随时间的推移而改变的数据,对它们进行统计,可先将常用统计方法的结果保存起来,避免每次查询时都需重新统计。

(9)书写规范的SQL语句

1)在 Where 字句中检索字段上加索引,若为多字段联合检索,可在这些字段上加复合索引。一些表中经常被检索的字段未加索引。
如:MS_THMX 中的 CZGH、JZRQ。
若表中加了复合索引,在书写 Sql 语句时,and 语句中的字段应按复合索引中字段的先后顺序,否则索引会失效。
ZY_BQYZ表中加了在XMLX,YPLX复合索引,检索语句应写型如:
XMLX=1 AND YPLX=0
而不是 YPLX=0 AND XMLX=1
2)避免使用 Sql Server 函数,如 DateDiff(),函数会使索引失效。
例:
原 Sql 语句:
DATEDIFF(DAY, TZSJ, GETDATE())=0
优化的Sql 语句:
// 变量申明
datetime ldt_datebegin, ldt_dateend
ldt_datebegin = datetime(date(gf_server_date()), time(“0:0:0”))
ldt_dateend = datetime(date(gf_server_date()), time(“23:59:59”))
// Sql
TZSJ >= :ldt_datebegin AND TZSJ <= :ldt_dateend
3)少用字符串类型字段,多用数值型字段
要与其他表作连接用的字段,最好用数值型。因为,一般字符型位数相对数值型较长。用数值型字段,可减少 Sql Server 检索比较的时间。
4)尽量少用 OR 子句
OR 子句将导致 Sql Server 用 Nested Loop 的方法检索数据
IN 子句中若为常量,Sql Server 实际上是转化为 OR 语句来实现。
5)IN 子句中应为常量,避免用子查询
如:医嘱项目执行模块,原来的 Sql 语句片段为:
(ZXKS=0 OR ZXKS IS NULL OR ZXKS IN (SELECT KSDM AS ZXKS FROM GY_KSWK WHERE WKDZ=:as_wkdz)
优化为:
(ZXKS=0 OR ZXKS IS NULL OR ZXKS IN (:ala_ksdm))
其中,ALA_KSDM 为数值数组
6)避免用 IS NULL 或 ISNULL(FYDJ*FYSL,0)=0 类似的语句
在表设计时,要有初值(BSHIS2.2已考虑此问题)。ISNULL() 将使索引失效。
如果一定要用,请使用 IS NULL,而不使用 ISNULL() 函数。
7)避免使用子查询,子查询将导致 Sql Server 用 Nested Loop 的方法检索数据。
特别是相关子查询要少用。
无关子查询:
SELECT * FROM ZY_FYMX WHERE ZYH IN (SELECT ZYH FROM ZY_BRRY WHERE CYPB=8)
以上与下面的相同
SELECT ZY_FYMX.* FROM ZY_FYMX, ZY_BRRY WHERE
ZY_BRRY.CYPB=8
相关子查询
SELECT KSDM,
(SELECT TOP 1 WKDZ FROM GY_KSWK WHERE GY_KSWK.KSDM=
GY_KSDM.KSDM) AS WKDZ
FROM GY_KSDM
即一个或多个字段与外部的数据集相关联的子查询,这种查询效率很差

(10)大查询避免在网络上进行大批量的数据传输

功能进行GROUP BY 的或者先进行汇总的先在SQL语句中去实现,不要到DATAWINDOW中去汇总处理。
典型的败笔:
门诊医生站系统的科室就诊情况统计

(11)不要一边执行代码,一边还使用SQL语句查询,这样会很慢的。应该尽可能地将所要的数据先一次性检索出来,然后在本地用 DATAWINDOW 或者 DATASTORE 的 FILTER处理。

4、医保接口设计规范

请参考《HIS医保接口设计规范(草稿).doc》
最关键的原则:1)将医保业务和HIS业务分割开
2)医保一般以地区为单位,要保证同个地区的医保处理程序一致

5、PB程序书写注意点和技巧

(1)PB更新的主键问题

PB的DATAWINDOW在设置UPDATE属性时,本来可以按“Primary Key”获得主键的,但是PB经常出现错误,找到的不是表的主键,而是其他字段。这时需要程序员自己设置好主键。(如:his2.2x药房系统的w_fycl的基本医嘱处理DATAWINOW)
下面的界面中,按了“Primary Key”按钮获得主键错误,需要手工设置。务必注意。

(2)DATAWINDOW的更新类型

即UPDATE属性页的“Where Clause for Update/Delete”
请根据实际需要设置选择类型
1)“Key Columns只据主键进行更新,不能保证并发,易覆盖
2)“Key and Updateable Columns可保证数据一致,不能同时更新
3)“Key and Modified Columns尽可能地保证同时更新
具体情况和详细解释可参考相关的书籍。
1)一般的数据维护,如:药库基本信息、自负比例维护维护,按1)类型即可
2)病区药房发药,避免同时处理同一批数据,让一方处理后,另一方就不能处理。可用第二种更新类型。其他还有,药房申领单确认和输入模块,它和药库出库单处理的是同一批数据,为了避免并发,可采用2)更新类型。
3)用的较少,数据完整性差,不过有时候为了时很多用户能对同一批数据进行操作,才这样做。(可举例说明为什么说数据一致性差)

(3)PB自定义对象和窗口打开时出现非法指令退出怎么办

这个是PB的一个很大的Bug,PB6.5和PB6.0都存在这个问题
只要多打开几次就可以了
典型的是:杭州医保的对象,打开的时候就有这样的问题。

(4)PB对象或者窗口模块保存时,不能保存,老出现非法指令怎么办

1)方法一:任意找对象或者窗口事件的代码,在第一行的前面加空行,然后保存试试
2)方法二:将对象或者窗口export成文本文件进行修改(一般插空行),然后再import进去试试看。

(5)代码执行时,出现莫名其妙的非法退出,或者显示内存页不正确的问题

这个问题一般是由于DLL的函数调用后引起的。
并且,此错误在 debugbreak 状态下是不能测试出来的。也不是每次都出现,同个模块多运行几次可能出现此问题。若要跟踪,请用messagebox来处理,可定位到哪里出现错误。
此问题的一般原因是,DLL的函数有string 或其他结构类型的参数变量,并且是 ref 类型的,即同时做为参数和函数的返回。请注意检查初始空间设置,若不足,则PB在处理多次后,就出现错误。一定要满足其最小的空间设置。
如:GetComupterName(ref string ls_name)
下面是调用的地方:
string ls_name
//ls_name = space(200) // 错误
ls_name = space(255) // 正确
GetComupterName(ls_name)

(6)关于修改DATAWINDOW的注意点

修改了DATAWINDOW的字段列表属性或者其他一些外观属性要检查UPDATE属性页是否被修改变成不能更新数据了。PB在修改了一些属性后,将自动设置为不可更新DATAWINDOW。

(7)关于显示和打印DATAWINDOW两个DATAWINDOW的数据共享和复制

BSHIS在很多模块,都是使用sharedata 来共享或者用rowscopy来复制显示和打印两个DATAWINDOW之间的数据,所以修改了其中的一个后,必须保持两个DATAWINDOW之间字段列表的一致性,避免不能打印。
知识点:PB中,若两个DATAWINDOW的SQL中字段列表不同,不能SHAREDATA和使用rowscopy 复制数据。以前是FoxPro 的程序员请注意,FoxPro的 Append From 命令是不一定要字段列表同的,FoxPro 将根据字段名和顺序自动匹配,而PB不会匹配。

(8)书写必要的程序注释

可使用公司很多人现在在使用的PBCOMMENT工具帮助书写注释
关于注释有三点要注意:
1)函数和事件的开头要写注释
可用PBCOMMENT帮助书写,这个工具将自动产生必要的参数数据、返回值类型等,可减轻大部分的程序员的工作量。我们在此基础上再做些解释即可。

2)代码中,要做阶段性的注释,介绍代码段的功能,具体可看看HIS2.21的住院结算系统
这样做,我们可以清晰地理清程序结构,可以从整理上把握程序的框架和大体的实现。

3)在别人代码的基础上新增、修改、删除代码
这个是技术支持人员和工程实施人员在修改程序时经常遇到的问题。
在原来代码基础上新增代码:

在原来代码基础上修改代码:

在原来代码基础上删除代码:

(9)事务控制

避免gf_begin_transaction 语句和 gf_commit_transaction 在不同的函数和事件中对一个事务进行控制,提高程序的可读性。

(10)面向对象的程序设计

设计建议:对象内部调用用对象函数,外部调用对象功能用对象的事件,这样可区分接口函数和实现函数,利于程序维护。或者内部使用的函数前缀全部用uf_ 外部使用函数前缀全部用 of_ 。
要充分使用面向对象的程序设计方法,提高程序的可移植性和逻辑上的独立性。
注意事项:,对已经设计好的对象加属性或者功能,千万不能引用全局变量或直接用对象外部模块的名字(如:窗口的名字),这样会导致对象封装的失败。比没有使用面向对象还差。

(11)脚本显示层次化(利用Tab健缩格)

(12)建议一个函数/事件脚本的总行数不超过200行。

(13)如何处理有时候用DATASTORE 或者DATAWINOW更新数据后,看不到出错信息的问题。

嵌入式SQL的执行情况,我们可以看 sqlca. SQLErrText 看出来出错信息。
用DATAWINDOW更新(调用update()方法后),需要设置窗口的实例变量,然后在DATAWINDOW的dberror事件中设置保存错误信息,如:is_error = sqlerrtext ,然后在其他地方可以访问 is_error
用 DATASTORE(调用update()方法后),特别是动态的DATASOTRE,我们没有办法给PB对象动态设置脚本代码,可以这样做,先做个祖先类,u_datastore 是从 PB类DATASOTRE 继承的,并新增该对象的实例变量 is_error,然后也在dberror事件中设置保存错误信息,如:is_error = sqlerrtext,以后就可以访问该对象的is_error 实例变量了。

(14)在客户化的过程,要注意程序的通用性

现在发现很多的程序错误和出现问题,很大一部分是由于程序跨医院不通用引起的。
这一点技术支持的程序员可能稍微好点,在外面修改程序工程人员就比较的欠缺。
导致程序客户化缺乏通用性的原因,一般有以下几点:
1) 时间紧,任务重
做通用的程序相对要求有充裕的时间。
解决方法:可以先做的不通用,然后再抽空将其修改为通用的程序。
2) 程序员缺乏做通用程序的意识
新来的员工没养成习惯,有时候经常带有学校里的编程习惯。不知道商业软件应该具备通用、稳定、实用特性。有些老程序员习惯差,没有做通用程序的习惯,应付了事。
解决方法:加强培训和对程序员的监督管理,必要时追究当事人的责任,
新程序员可以向老程序咨询这方面的知识。
3) 做通用程序的一些注意点
关于SQL语句的书写:最好大小写和实际字段名同,避免大小写敏导致的不通用
外连接的书写(具体请参考相关数据库的书籍)
不要写某个数据库专用的SQL语法(如:CASE语句)
FROM 表名(nolock) 语句其他数据库不通用
程序编制习惯: 不要对单个费用项目特殊处理不用系统参数,直接写数字
报表不要做定死的报表(报表中项目定死、格式不能随项目变化而变化、落款定死如操作员或者相关人员的名字)
报表和其他查询模块的DATAWINDOW中一般不能用计算机本地时间(即today()和time()函数,而应该取服务器时间)
不能同个医院程序不同科室或者不同使用者版本不同,可加系统参数、菜单权限来实现不同(医技系统的FSPH
不要动不动就试图新增模块,尽量采用已有的模块和流程
尽量采用面向对象的设计方法,以便程序移植和减少对当地医院业务的依赖(如:处方打印模块)
书写必要的注释
如何做一个通用报表
相关配合工作: 书写必要的表结构修改资料,一般建议用直接可执行的SQL
语句,新增表和新增字段分开写
新增字段:
-- 其他金额
ALTER TABLE ZY_FYMX ADD QTJE numeric(12,2) NOT NULL DEFAULT 0;
书写操作习惯和界面修改资料

6、书写必要的程序修改文档和相关的表结构修改SQL

(1)程序修改记录

修改记录文件书写注意点;
1) 书写语句要简洁,用说明文的风格,不要用记叙文或其他议论文等格式
2) 尽量分条目,这样利于阅读。并建议建立段落使生成文档结构图
3) 版面要清晰、简单,因为这个文件很多是要发到医院里给他们看的
4) 整理出自己的文档格式模板,也可到其他技术人员那里获得比较好个模板
5) 必要时书写段落程序,写出关键修改的地方
6) 图文并茂说明问题,特别是新增模块和新增报表和对原来界面的调整,有时候很难用语言表达
7) 分段落说明问题,不要写在一段里,看起来很乱
典型的关键字有:
问题描述、使用时间、程序修改、错误原因、注意事项、表结构调整等
下面是个例子:
门诊系统:性能问题:门诊日报经常导致锁表和速度很慢
说明门诊日报经常导致锁表和速度很慢,一般发生在8:30到10:30最忙的时候发生,在这段时间做报表的人一般是上一天晚班的人。
原因分析主要是在此模块检索数据时用了游标和写SQL语句的时候没写规范的SQL语句和使用SQL的一些技巧,而二院到目前位置数据量已经很大了。
修改:将所以用游标的地方改为使用DATAWINDOW,并修改SQL语句为规范的SQL语句,同时在FROM 的表名后加(NOLOCK),可使SQL启用无锁读取,减少锁表。

(2)写“若干注意事项”

程序修改导致的操作流程的修改和变动,需要写《XXXX__若干注意事项》
主要写,修改了程序后新增必要的数据准备、流程调整、操作注意点等
这样,可帮助工程实施人员很快的理解和使用新的程序
可参考《bshis2.x宁波新医保__若干注意事项.txt》

(3)写“牵涉的系统修改文件程序存放目录”

帮助程序文档管理人员,将最新和好用的程序准确地交给工程实施人员。
主要说明修改了哪些系统即可。

(4)表结构修改SQL文件

1) 字段修改文件(下面是《bshis2.x宁波新医保__新增字段.sql》的部分内容)
------------------------------------------------------------------------------------------
-- 宁波新医保接口在HIS表里加了以下一些字段
-- Written by li qun wei, 03/06/2002
-- for MS SQL or Sybase
-- last update: li qunwei, 03/12/2002
------------------------------------------------------------------------------------------
--MS_BRDA表
--卡内信息
ALTER TABLE MS_BRDA ADD KNXX varchar (30) NULL ;
--医保卡号
ALTER TABLE MS_BRDA ADD YBKH varchar (20) NULL ;
--帐号标志
ALTER TABLE MS_BRDA ADD ZHBZ varchar(10) NULL ;

--在ZY_BRDA表里加了
--医保卡号
ALTER TABLE ZY_BRDA ADD YBKH varchar (20) NULL ;

2)新增表
可用PowerDesign 或者 SQL Server 的企业管理工具生成SQL语句
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐