Software Project Management Standards
SUNTEK R&D SPMS (流程管理)流程编写规范
IVR流程编写规范
IVRCodingStandard
编制单位:新太科技技术开发中心
编制时间:2004/2/20
文档编号:SPMS-SEP-12
版本号:内部试用版
变更记录
A-ADDED M-MODIFIED D-DELETED
目录
1.目的4
2.说明4
3.流程规范4
3.1组织结构4
3.2排版4
3.3注释6
3.4命名11
3.5变量12
3.6状态13
3.7函数14
3.8流程动作基本约定18
1.目的
本部分编写规范适用于新太IPS流程编写。
2.说明
本规范作为壹个标准的IPS流程编写规范,其中对于规则是必须遵守的,建议是提醒您需要注意的地方,或者是于该情况下壹个较好的选择。
3.流程规范
3.1组织结构
规则1-1:于流程文件存放的根目录下,只能有.sc、.cod、.ini文件。其他的文件,按所属业务不同存放于不同的目录下,保持流程的根目录清洁。
建议1-1:不同类型文件按类型分目录存放,原则是要类型分明,便于管理,便于过期删除,目录下文件如果有无限增长的趋势,请按壹定规则(例如日期)分目录存放。
建议1-2:放音动作所需的语音文件.vox/.v41文件,于./vox/目录存放;流程图等文档说明于./doc/目录下存放。
3.2排版
规则2-1:流程中各状态块间保留1行空行。
规则2-2:函数之间保留3行空行。
规则2-3:流程头部配置参数、宏、函数、全局变量定义区域按先后顺序分开且注释含义,便于查找。
例1:
//*************************************************************
//流程配置参数定义
//*************************************************************
#iniparamstring@sAgentStartTime//座席开始服务时间
#iniparamstring@sAgentStopTime//座席结束服务时间
#iniparamstring@sCurrencyFaxFile//货币代码传真文件
#iniparamint@nMaxTalkRecs//系统最大的可说资源数
//************************Endof配置文件***********************
//*************************************************************
//流程宏定义
//*************************************************************
#defineINPUTERRLIMIT3//输入错误次数限制
#defineACCOUTLENGTH23//账号长度(最长)
#defineMAINPATH".\\sysvox\\"//主函数语音文件根目录
#defineMAINVOX1"NQQWel.vox"//您好,QQ现已开通千里音缘服务#defineMAINVOX2"NQQCity.vox"//千里音缘目前已开放四川、海南俩地//************************Endof宏定义***********************
//*************************************************************
//流程函数定义
//*************************************************************
#functionmain//主函数
#functionOnClear_QQCallOut//异常处理函数
//************************Endof函数定义***********************
//*************************************************************
//流程全局变量定义
//*************************************************************
#declareSRg_sAstring="Thisisastring"//壹个全局使用的数据串
#declareFRg_fMyMoney=10.5//壹个全局使用浮点数,表示金额
#declareIRg_nCount//整型全局变量表示数目
//************************Endof全局变量***********************
规则2-4:使用不同编辑工具时,要求定义Tab键为4个空格位(不要用空格填充)。
规则2-5:函数体里状态左缩进壹个Tab键,保持左对齐,该状态下的动作、事件语句左缩进壹个Tab键,保持左对齐。
规则2-6:流程动作语句中,“[”符号右边保留壹个空格;“]”符号左边保留壹个空格;流程动作中参数分隔符“,”右边保留壹个空格。
规则2-7:流程动作语句中,状态跳转符号“->”之前至少要保留壹个TAB 键(最好同壹个状态下的所有->符号均对齐),“->”之后要保留壹个空格。
例2:
:stNationalQQCallIn//外省用户呼入
[Strsub$CallerID,1,2]
[EqualSR0,"13"]
Passed->stLocalQQNormal//本地用户
Failed->stNationalQQCall//外地用户
规则2-8:iniparam,define,declare等定义时,第二个参数和第三个参数之间用壹个或者多个Tab键间隔开,以对齐美观为准。示例参见上面例1。
3.3注释
规则3-1:壹般情况下,源程序有效注释量必须于20%之上。
说明:注释的原则是有助于对程序的阅读理解,于该加的地方均加了,注释不宜太多也不能太少,注释语言必须准确、易懂、简洁。
规则3-2:流程头部配置参数、宏、函数、全局变量定义区域按先后顺序分开且注释含义。示例参见上面例1。
规则3-3:流程头部必须注明各种配置参数使用约定。
规则3-4:于流程头部定义全局变量的同时须明确列出该全局变量的含义及使用方案。
例3:
//***********************全局变量****************************
#declareIRg_nLeaveWordType=0//留言类型0发送留言,1转发留言,2回复留言
#declareIRg_nCanChoose=1//收听用户资料时是否能够按键选择
#declareSRg_sYWBegintime=""//当前业务开始时间字符串yyyy-mm-ddhh:mm:ss
//**********************Endof全局变量***********************
规则3-5:流程头部必须有自定义函数功能介绍。
规则3-6:函数体开始之前必须有传入、传出参数解释,函数返回值解释。
返回值的壹般0表示正常,1表示有错,9表示异常退出,4表示转座席、8回主流程、7回上级菜单。
例4:
//*********************************************************
//Functionname:FormatTxtFile
//Functionusage:用于将文本文件转换成传真文件
//
//传入参数:
//g_sTxtFileName:需要转换的文本文件;
//传出参数:
//g_sFaxFileName:转换后的传真文件名;
//Returned:0转换成功;9异常错误;
//
//厦门建行客服中心
//编写日期:03/22/2001
//*********************************************************
规则3-7:子函数必须有编写/修改日期。示例参见例4。
规则3-8:如果有和网关交易部分必须明确收发包格式。
例5:
//**********************************************************
//functionname:funcTrans282600
//functionusage:对公业务-修改电话银行密码
//
//传入参数:
//传出参数:
//Returned:0修改成功;9连接数据库失败
//
//上传报文:|282600|9999||帐号|密码|^
//下传报文:|282600|返回码|^
//**********************************************************
规则3-9:注释应和其描述的代码相近,对子函数代码的注释应放于其上方,需和其上面的代码用空行隔开;对函数中代码的注释应置于右方相邻位置,不可放于下面。
规则3-10:流程文件中尽量使代码右方注释处于同壹列,方便阅读理解。
规则3-11:流程中重要部分壹定要注释。例如菜单选择后状态跳转。
规则3-12:涉及数据库操作必须注明实际SQL。
说明:明确数据库操作目的,方便后期调试、测试核对流程。
例6:
//************查询不得注册用户黑名单(如电话卡用户)*************
//functionname:funcQueryRegBlacklist
//functionusage:查询主叫号码是否于不得注册用户黑名单(如电话卡用户)
//传入参数:主叫号码$CallerID
//传出参数:无
//Returned:0表示非黑名单用户1为黑名单用户2为数据库超时
//****************************************************************
funcQueryRegBlackList
{
#declareIRm_nReturn=0//返回值
:stWait
[Assigng_sSQL,"select*fromqq_RegBlacklistwhereF_callerlike'"] [StrCatg_sSQL,$CallerID]
[StrCatg_sSQL,"%'"]
[ExecSQLg_sSQL]//select*fromqq_RegBlacklist
//whereF_callerlike‘%%’Passed->stIsBlacklist
Failed->stNotBlackList
TimeOut->stTimeout
:stIsBlacklist
[Assignm_nReturn,1]//1表示是黑名单用户
[ClearDTMF]
[SetDTMF"?"]
[AssignSR0,MAINPATH]
[StrcatSR0,MAINVOX29]
[PlayFileSR0]//“本用户不能进行注册”
StopPlayBack->stExit
DialTerminate->stExit
Failed->stExit
:stNotBlackList
[Assignm_nReturn,0]//0表示非黑名单用户
->stExit
:stTimeout
[Assignm_nReturn,2]//2表示数据库超时
->stExit
:stExit
[Returnm_nReturn]
}
//************Endof查询不得注册用户黑名单***************
规则3-13:播放语音必须注释放音实际文字。
便于核对流程,以及方便阅读,以及语音文件遗失情况下恢复
例7:
:stBegin
[ClearDTMF]
[SetDTMF"12"]
[AssignSR0,INCARDPATH]
[StrcatSR0,REGINPUTVOX1]//请输入您的个人资料,男生按1,女生按2
[PlayFileSR0]
StopPlayBack->stSelectSex//选择性别
DialTerminate->stSelectSex
Failed->stSelectSex
规则3-14:于流程中使用到全局变量必须注释用途含义,保持全局变量含义统壹,避免于另外壹处改变其含义。
例8:
:stPromptUserType1
[Assigng_nUserType,1]//用户权限为1级管理员
[ClearDTMF]
[SetDTMF"?"]
[AssignSR1,PROMPTUSERTYPEPATH]
[StrcatSR1,PROMPTUSERTYPE1]//您好,您是本聊天室的1级管理员
[PlayFileSR1]
StopPlayBack->stExit0
DialTerminate->stExit0
Failed->stExit0
规则3-15:边写代码边注释,修改代码同时修改相应注释,以保证注释和代码壹致性。没用的注释要及时删除。
规则3-16:注释内容要清楚、明了,含义准确,防止二义性。
规则3-17:避免于注释中使用缩写,特别是非常用缩写
说明:于使用缩写时或之前,应对缩写进行必要说明。
建议3-1:通过对函数或状态、变量等正确命名,使流程代码成为自注释的。
3.4命名
规则4-1:状态、变量、函数命名只能使用英文字母、下划线以及数字的组合。应当尽量使用常规的英文或英文缩写,避免使用无法阅读理解的命名方式。
规则4-2:配置文件参数,如果是字符串string类型的以“@s”做为前缀;如果是整数int类型的则以“@n”做为前缀。
例9:
#iniparamint@nMaxTalkRecs//系统最大的可说资源数
#iniparamstring@sCurrencyFaxFile//货币代码传真文件
规则4-3:宏定义必须全部大写。示例参见上面例1中的宏定义。
规则4-4:全局变量命名参见规则5-1“全局变量命名”。
规则4-5:局部变量命名参见规则5-2“局部变量命名”。
规则4-6:状态命名参见规则6-1“状态命名约定”。
规则4-7:函数命名参见规则7-2“主函数命名”、规则7-4、规则7-5“自定义子函数命名”、规则7-6“自定义例外处理函数命名”。
规则4-8:命名要清晰、明了,有明确含义,同时使用完整的单词或大家基本能够理解的缩写。
说明:较短的单词可通过去掉元音形成缩写,较长的单词可取单词的头几个字母形成缩写,单词的第壹个字母大写。壹些单词有大家公认的缩写。
例10:
如下单词的缩写能够被大家基本认可。
Send可缩写为Snd;
Receive可缩写为Rcv
temp可缩写为Tmp;
flag可缩写为Flg;
statistic可缩写为Stat;
status可缩写为Sta;
message可缩写为Msg;
规则4-9:命名中若使用特殊约定或缩写,则要有注释说明。
规则4-10:用正确的反义词组命名具有互斥意义的变量或相反动作的函数等。
例11:begin/endcreate/destroyinsert/deleteput/getmin/max等。3.5变量
规则5-1:全局变量命名要以g_开头(g表示global),如果是字符串类型的则为g_s做前缀,如果是整型的则以g_n做前缀,如果是浮点型的则以g_f做前缀。
例12:
#declareSRg_sAstring="Thisisastring"
#declareFRg_fMyMoney=10.5
#declareIRg_nCount
规则5-2:局部变量命名要以m_为前缀(m表示member),如果SR类型的则为m_s做前缀,如果是IR类型的则以m_n做前缀。
例13:
#declareSRm_sAstring="Thisisastring"
#declareFRm_fMyMoney=10.5
#declareIRm_nCount
规则5-3:全局变量定义区域参见规则2-3“流程头部配置参数、宏、函数、全局变量定义区域”,示例参见例1。
规则5-4:参见规则3-4“于流程头部定义全局变量的同时须明确列出该全局变量的含义及使用方案”。
规则5-5:变量命名尽量符合该变量实际含义。
规则5-6:去掉没有必要的全局变量,函数内部尽量使用局部变量。
说明:全局变量是增大模块间耦合的原因之壹,故应减少没必要的全局变量以降低耦合度。
规则5-7:于流程开头仔细定义且明确全局变量的含义、作用、取值范围及全局变量间的关系。
规则5-8:当向全局变量传递数据时,要十分小心,防止赋予不合理的值或越界等现象
说明:当向全局变量传递数据时,应进行合法性检查,且于该行对变量含义做注释说明。
规则5-9:寄存器变量使用壹般作为IVR系统函数传递参数/返回值使用。流程内部自定义函数不推荐使用寄存器变量。除了动作返回值等不得不使用寄存器变量的情况外,壹律不使用寄存器变量,用自定义变量代替。
规则5-10:参见规则3-14“于流程中使用到全局变量必须注释用途含义,保持全局变量含义统壹,避免于另外壹处改变其含义”。
规则5-11:防止局部变量和全局变量同名。
规则5-12:严禁使用未经初始化的变量作为赋值。
建议5-1:建议不使用IR0或者SR0作为后续状态的变量,特别的,如果要超过3个状态后仍然需要使用当前IR0或SR0的值,先把IR0或SR0赋值给其他变量中保存。
3.6状态
规则6-1:状态命名约定以“st”开头,第三个字母大写表示实际有含义的
名称开始。
例14:
:stWait
Connect->stGetTime
:stGetTime
[NowTime]
[Assignm_sTime,SR0]
规则6-2:函数中以状态stWait开始,以状态stExit结束。示例参见下面例15、例17。
规则6-3:状态跳转为事件所驱动。
3.7函数
规则7-1:于壹个业务流程程序里面只能有壹个主函数。
规则7-2:主函数只能名为main,于开始壹个业务流程的时候自动执行。
规则7-3:于壹个业务流程程序里面能够有多个子函数。
规则7-4:子函数名不能为main。
规则7-5:自定义子函数除例外处理函数外,命名要以“func”开头,第五个字母大写表示实际有含义的名称开始,尽量表示该函数执行的具体功能、操作。
例15:
//**************************通用聊天过程************************
//functionname:funcChatProcess
//functionusage:通用聊天过程
//输入参数:g_nChatID聊天室编号,g_nChatType加入聊天的方式,g_nQQIdentify加入聊天身份,
//g_nTalkTime聊天时长,g_nIsFullExit当没可说资源时是否退出来,于主题聊天时会用到要退出
//输出参数:无
//返回值0正常退出,1对碰中退出,2聊天室编号不存于,3其他错误,4没可说资源的退出
//****************************************************************
//通用聊天过程
//****************************************************************
funcChatProcess
{
:stWait
//actionhere.
:stExit
}
//**********************Endof通用聊天过程**********************
规则7-6:流程自定义例外处理函数,以“OnClear_”为前缀。
例16:
#functionOnClear_QQCallOutClear//电话QQ呼出异常处理函数
#functionOnClear_sslwCountTime//三省联网统计互拨时长
规则7-7:流程中每壹层菜单是独立函数,每壹个选择项是独立函数。
规则7-8:于自定义函数开头须注释该函数的功能说明,详细传递参数、返回值的各种含义。示例参见例15。
规则7-9:传入、传出参数尽量使用自定义全局变量,除系统规定外不推荐使用寄存器。承担函数传递参数的全局变量命名要符合变量命名规则。
规则7-10:子函数返回值约定,通常约定返回值0表示成功,其他值表示其他不成功原因。
目前已经形成的壹些基本约定
A,Returened(9)表示出错需要主动退出流程,如资源分配失败/放音失败等
B,Returened(8)表示需要回到主流程
C,Returened(7)表示只需回到上层菜单
D,Returened(4)表示转坐席后退出
E,其他返回值暂定回到上壹级菜单
F,每个函数后均需要处理Returned(-1)事件
例17:
//**************************************************************** //连接坐席
//**************************************************************** funcConnectAgent
{
#declareIRm_nReturnedCode//标识子函数退出状态
:stWait
[Equalg_nData,0]//判断传入参数
->stStar
:stStar
//actionhere.
//…
//…
:stSuccess
[Assignm_nReturnedCode,0]//正常连接坐席成功
->stExit
:stAgentExit
[Assignm_nReturnedCode,4]//转坐席后退出
->stExit
:stMainMenu
[Assignm_nReturnedCode,8]//回到主流程
->stExit
:stPreMenu
[Assignm_nReturnedCode,7]//回到上层菜单
->stExit
:stExitFlow
[Assignm_nReturnedCode,9]//出错需要主动退出流程
->stExit
:stExit
[Returnm_nReturnedCode]
}
//**********************Endof连接坐席**********************
规则7-11:子函数代码结束添加注释“EndofXXXX”独立壹行表示结束。示例参见上面例15、例17。
建议7-1:壹个函数仅完成壹件功能。
建议7-2:不要设计多用途面面俱到的函数。
说明:这会使理解、测试、维护变得困难。
建议7-3:函数的功能应该是能够预测的,也就是只要输入数据相同就应产生同样的输出。
建议7-4:尽量不要编写依赖于其他函数内部实现的函数。
建议7-5:检查函数所有数据输入的有效性,如语音文件路径、全局寄存器、自定义全局变量等。
建议7-6:函数名应准确描述函数的功能/操作。
建议7-7:尽量使用动宾词组为执行某操作的函数命名。
建议7-8:避免使用无意义或含义不清的动词为函数命名。
建议7-9:避免函数中不必要语句,防止流程中的垃圾代码,尽量减少流程代码的行数。
建议7-10:功能不明确且较小的函数,特别是仅有壹个上级函数调用它时,
应考虑把它合且到上级函数中而不必单独存于。
3.8流程动作基本约定
规则8-1:流程中等待输入三次没有按键响应(超时)或连续三次输入出错,应返回上壹级菜单。
规则8-2:主菜单等待输入三次没有响应(超时)或连续三次输入出错应该退出流程。不能让其无休止的循环。确保流程于无人干预的情况下能够自动退出流程。
规则8-3:流程中所有的有分支走向的动作,必须处理Event(-1)的事件,如Returned(-1),避免出现流程挂死。
建议8-1:涉及到数据库操作建议尽量使用ExecSQL动作,不推荐使用DBSelect/DBInsert/DBDelete/DBUpdate等通过DBINTERFACE间接操作的做法。示例参见例6中的ExecSQL动作。
―――――――――――――――――END―――――――――――――――