M通用版代码规范 - 持续更新
文章目录
- M通用版代码规范 - 持续更新
- 变量
- 方法
- 类
- 锁
- 事务
- 陷阱
- 格式
- 空行
- 注释
M通用版代码规范 - 持续更新
变量
- 代码中的命名均不能
$
、#
等特殊符号开始或结束,因为$
、#
等是系统方法、变量,禁止混淆。
反例:
$name
_name
正例:
name
- 严禁代码中使用拼音与英文混合方式命名,更不允许直接使用中文。
反例:
Dazhe
getDZname
[打折]
正例:
discount
getDiscountName
- 参数名、成员变量、局部变量都统一使用
lowerCamelCase
风格。
反例:
Params
正例:
params
- 常量命名全部大写。力求完整语义表达清楚,不要嫌长。
反例:
MaxCount = 10
正例:
MAXCOUNT = 10
- 杜绝不规范缩写,避免词不达意。
反例:
com
condi
正例:
complete
condition
- 长度为7个以内单词不需要缩写,当变量长度过长时需考虑缩写,且缩写应为常用正规缩写,避免无意义缩写。
反例:
st
nb
正例:
start
number
num
- 避免无意义变量。
反例:
s a = "1"
s b = "2"
s c = a * b
正例:
s fitstNum = "1"
s secondNum = "2"
s sum = firstNum * secondNum
- 临时
global
、进程global
命名严格使用^TMP
、^||TMP
,且携带pid
。格式为领域名 + 类名 + 方法 + pid + 标识
。
- 提前把
TMP
开头的global
名称配置到临时TEMP
命名空间,配置不写日志。
反例:
s ^||YX("TMP", pid, "Login")
正例:
s ^||TMP("IRIS", "IRIS.MOB.Base", "Login", pid)
- 布尔变量不要用
is
开头,因为其他框架引用的话会解析错误。例如Java
的Getter
的方法也叫isDisp()
。
反例:
isDisp
正例:
dispFlag
- 所有表的
ID
,都用表的前缀。
反例:
BS_IRIS_Student
:ID
CF_IRIS_Config
:configID
正例:
BS_IRIS_Student
:bis
CF_IRIS_Config
:cic
- 所有引用
global
数据的变量,用表ID + data
方式命名,多节点用ID + 节点 + Data
方式。
反例:
s data=^BS.IRIS.StudentD(inci)
正例:
s bisData = ^BS.IRIS.StudentD(inci)
- 方法中仅出现一次
dataStr
分割字符串分割索引均为i
长度均为len
。
反例:
s prescNolen=$l(prescNoStr, ",")
f index = 1 : 1 : len q:ret'=0 d
.s prescNo = $p(prescNoStr, ",", index)
正例:
s len = $l(prescNoStr, ",")
for i = 1 : 1 : len {s prescNo = $p(prescNoStr, ",", i)
}
- 创建的私有对象可以加
m
,例如有Execute
类的初始化对象。
反例:
s execute = ##(IRIS.Execute).%New()
正例:
s mExecute = ##(IRIS.Execute).%New()
- 不要将系统保留字或
SQL
保留字做为变量。
反例:
s SQLCODE="0"
正例:
s code = "0"
- 对于调用其他方法获取返回值的变量,禁止使用
err
的名称,推荐ret
。
反例:
s errRet=##class(XXX).Save()
s retErr=##class(XXX).Save()
正例:
s ret = ##class(XXX).Save()
- 禁止变量超过
31
个字符。(局部变量名称限制为31
个字符。可以指定长度超过31
个字符的名称,但仅使用前31
个字符。)
示例:
ClassMethod Var()
{s abcdefghiklmnopqrstuvwxzy123456789 = "1"w abcdefghiklmnopqrstuvwxzy123456789,!s fitst = 1s fitstSum = fitst +abcdefghiklmnopqrstuvwxzy123456789w fitstSum,!s second = 2s abcdefghiklmnopqrstuvwxzy1234567891 = "2"w abcdefghiklmnopqrstuvwxzy1234567891,!s secondSum = second + abcdefghiklmnopqrstuvwxzy123456789w secondSum,!b
}
结果:
DHC-APP>d ##class(M82).Var()
1
2
2
4b }^
<BREAK>zVar+11^M82.1
DHC-APP 2d1>w<Private variables>
abcdefghiklmnopqrstuvwxzy123456=2
fitst=1
fitstSum=2
second=2
secondSum=4
- 百分比变量命名要以
%z
开头,避免与系统变量冲突。
反例:
s %msg = ""
正例:
s %zXX("XX") = ""
.inc
文件里的通用变量,为了防止与系统变量重复。加上前缀标识。
反例:
#define Error "XX"
正例:
#define XXError "XX"
方法
- 类名、方法名使用
UpperCamelCase
风格。
反例:
BS.iris.student
getname()
正例:
BS.IRIS.Student
GetName()
- 返回布尔类型方法以
Is
开头,例如是否存在。ture
为$$$YES
,false
为$$$NO
,方法后面加上As %Boolean
。
反例:
GetExistFlag()
正例:
ClassMethod IsExist(name) As %Boolean
{s bis = $o(^BS.IRIS.StudentD("Student", name, ""))q:(bis '= "") $$$YES q $$$NO
}
调用:
if(..IsExist(name)){// todo
}
q:..IsExist(name)
q:'..IsExist(name)
- 推荐使用动宾结构,函数名应清晰反应函数的用途和功能。
反例:
ObtainName()
正例:
GetName()
- 函数,方法名最长不超过
30
个字符。
反例:
DefineDeliveryProcessEvent()
正例:
SetDispEvent()
- 每个方法对应一个词
retrieve
、fetch
、find
、query
都有查询意思,manager
、handler
、controller
都有管理之意。我们只规定一种。查询就Query
,获取数据就Get
。
反例:
ObtaionSomething()
RetrieveSomething()
正例:
GetSomething()
QuerySomething()
- 一个方法尽量控制在
50
行(一屏)。如果过于庞大,就该重构。庞大的方法容易引起阅读疲劳,让人抓不住重点。代码逻辑要分主次,个性,共性。
反例:
ClassMethod Login(params)
{s info =""f s info = $o(^IRIS("info", info)) q:info="" d.s flag = $p(^IRIS("info", info), "^", 1).i flag = "Y" d.sql(insert .....)
}
正例:
ClassMethod Login(params)
{s info =""for {s info = $o(^IRIS("info", info))q:(info = "")s flag = $p(^IRIS("info", info), "^", 1)s ret = ..IsFlag(flag)continue:(ret)}
}
ClassMethod IsFlag(flag) as %Boolean
{if flag = "Y" {s ret = ..InsSomeThing()q:(ret '= 0) $$$NO}q $$$YES
}
ClassMethod InsSomeThing(flag)
{sql(insert .....)
}
- 方法内传递参数过多。考虑用对象方式来重构。
反例:
ClassMethod Login(params)
{s startDate = $p(params, "^" ,1)s endDate = $p(params, "^" ,2)s locID = $p(params, "^" ,3)s userID = $p(params, "^" ,4)s groupID = $p(params, "^" ,5)s ret = ..DoSomeThing(startDate, endDate, locID, userID , groupID)
}
ClassMethod DoSomeThing(startDate, endDate, locID, userID , groupID)
{s status = $o(^IRIS("Flag",flag,""))s other = $o(^IRIS("userID",userID,""))s flag = $o(^IRIS("flag","")s ret = ..DoSomeThingSub(startDate, endDate, locID, userID , groupID, flag , status, other)
}
ClassMethod DoSomeThingSub(startDate, endDate, locID, userID , groupID, flag , status, other)
{//to do
}
正例:
ClassMethod Login(params)
{s mLogin = ##class(PHA.OP.MOB.Login).%New()s mLogin.startDate = startDates mLogin.endDate = endDates mLogin.locID = locIDs mLogin.userID = startDates mLogin.groupID = groupIDd mLogin.Login()
}
Class IRIS.Login
{//各种属性
}
- 禁止在循环里直接写
sql
语句即&sql()
,应把sql
单独提出成方法。
- 禁止在公共查询里写涉及存储
sql
方法。 sql
语句应当单独建立类来保存,给予其他类调用。
反例:
ClassMethod Login(params)
{s info =""f s info = $o(^IRIS("info", info)) q:info="" d.s flag = $p(^IRIS("info", info), "^", 1).sql(insert .....)
}
正例:
ClassMethod Login(params)
{s info =""for {s info = $o(^IRIS("info", info))q:(info = "")s flag = $p(^IRIS("info", info), "^", 1)s ret = ..InsSomeThing(flag)}
}
ClassMethod InsSomeThing(flag)
{sql(insert .....)
}
- 非普通字符串的入参或返回值需要进行声明,以明确数据类型,如数组、对象、流、引用,
%Status
等数据类型。
反例:
/// desc: 入参为引用,返回为数组
classmethod Test(Param)
{}
正例:
/// desc: 入参为引用,返回为数组
classmethod Test(ByRef param) As %ArrayOfDataTypes
{}
- 当遇错误信息时,返回值不能单纯的返回负数,不能使用大于等于0的数值作为错误信息的标识。
- 字符串形式:负数^错误信息的格式
q "-1^代码重复"
json
形式:
q ..RetFail("代码重复")
/// w ##class(M.M83).Save()
ClassMethod Save()
{s ret = ..InsData()q:(ret.code < 0 ) ret.msgq $$$OK
}ClassMethod InsData()
{q ..RetFail("代码重复")
}ClassMethod RetFail(msg)
{s obj = {}s obj.code = -1s obj.msg = msgq obj
}
%Status
形式:
q $$$ERROR($$$GeneralError,"代码重复")
/// w ##class(M.M83).SaveStauts()
ClassMethod SaveStauts() As %Status
{s sc = ..InsDataStauts()q:$$$ISERR(sc) $System.Status.GetOneStatusText(sc)q $$$OK
}ClassMethod InsDataStauts() As %Status
{q $$$ERROR($$$GeneralError,"代码重复")
}
类
- 全部类以
IRIS.XX
开头。
反例:
Class XXX.XXX.XX
正例:
Class IRIS.XXX.XX
- 所有类里的方法,方法顺序按照常用顺序排序,最常用的最在上,依次。
- 类默认均为
ProcedureBlock
,禁止Not ProcedureBlock
,如需使用特殊字符@
等,单独建类或方法并定义Not ProcedureBlock
。
反例:
Class IRIS.Login Extends %RegisteredObject [not ProcedureBlock]
正例:
Class IRIS.Login Extends %RegisteredObject
锁
- 禁止直接锁表结构的
Global
。
反例:
l +^BS.IRIS.StudentD
- 加解锁必须加
+
、-
严格控制,必须成对出现。
反例:
l +^BS.IRIS.Student(1)
l +^BS.IRIS.Student(1)l -^BS.IRIS.Student(1)
正例:
l +^BS.IRIS.Student(1):3
l -^BS.IRIS.Student(1):3l +^BS.IRIS.Student(1):3
l -^BS.IRIS.Student(1):3
- 加锁必须要带
+
,否则导致解锁进程内所有锁。
反例:
l +^BS.IRIS.Student1(1)
l +^BS.IRIS.Student2(1)
l ^BS.IRIS.Student3(1)
正例:
l +^BS.IRIS.Student1(1):3
l +^BS.IRIS.Student2(1):3
l +^BS.IRIS.Student3(1):3
- 加锁必须写超时的退出,避免死锁,造成进程无限期阻塞。
正例:
l +^BS.IRIS.Student:3
- 自定义功能锁:
^产品组代码(产品线,规范代码:唯一标识)
(例如:单号)。
反例:
l ^TMPOP(lockName)
正例:
l +^IRIS("BIZ", "BOXNO:" _ boxNo):5
- 私有进程全局变量名不能用作锁名。
反例:
l +^||BS.IRIS.Student(1):3
正例:
l +^BS.IRIS.Student(1):3
- 禁止单独在程序中使用无参数锁。
反例:
lock
- 使用锁时一定要下标节点。
反例:
l +^BS.IRIS.Student
正例:
l +^BS.IRIS.Student(1):3
事务
- 严格禁止开放性事务。
反例:
ClassMethod Save()
{tstart
}
正例:
ClassMethod Save()
{tstc //或 tro
}
- 事务
ts
、tc
、tro
的位置应保持近距离,在一屏幕范围内,避免位置过远。代码过多应当提取成方法,让事务看起来简洁、语义明朗。
反例:
ClassMethod Save()
{ts/* 添加主表信息 */// todo 50行代码/* 添加明细信息 */// todo 100行代码tc
}
正例:
ClassMethod Save()
{ts/* 添加主表信息 */s sc = ..InsMain()i $$$ISERR(sc) troq:($$$ISERR(sc)) sc/* 添加明细信息 */s sc = ..InsDetail()i $$$ISERR(sc) troq:($$$ISERR(sc)) sctcq sc}
- 严格禁止跨方法提交事务。
反例:
ClassMethod Save()
{tss sc = ..InsMain()}
ClassMethod InsMain()
{// todotc
}
正例:
ClassMethod Save()
{tss sc = ..InsMain()tcq sc
}ClassMethod InsMain() as %Status
{// todo
}
- 为明确显示事务,事务命令需要简写并且小写。
反例:
ClassMethod Save()
{TSTART...TCOMMIT
}
正例:
ClassMethod Save()
{ts... // todotc
}
- 同一个方法内不应该出现事务嵌套的现象。
反例:
ClassMethod Save()
{tsts... // todotrotc... // todotstc
}
正例:
ClassMethod Save()
{ts... // todotc
}
- 事务应在保存程序的最外层。
反例:
ClassMethod Save()
{tss sc = ..InsMain()s sc = ..InsDetail()tc
}ClassMethod InsMain() as %Status
{ts// todotc
}ClassMethod InsDetail() as %Status
{ts// todotc
}
正例:
ClassMethod Save()
{tss sc = ..InsMain()i $$$ISERR(sc) troq:($$$ISERR(sc)) scs sc = ..InsDetail()i $$$ISERR(sc) troq:($$$ISERR(sc)) sctc
}ClassMethod InsMain() as %Status
{// todoq sc
}ClassMethod InsDetail() as %Status
{// todoq sc
}
- 单条
SQL
语句的数据保存不需要事务。
反例:
ClassMethod Save()
{ts&&sql()tc
}
正例:
ClassMethod Save()
{&&sql()
}
ts
,tc
首尾添加空行
,或者注释
.。
反例:
ClassMethod Save()
{TSTARTs ret=..SaveMain()...s retItm=..SaveDetail()...TCOMMIT
}ClassMethod SaveMain()
{TSTART...TCOMMIT
}ClassMethod SaveDetail()
{TSTART...TCOMMIT
}
正例:
ClassMethod Save()
{ts/* 注释 */s ret = ..SaveMain()i ret < 0 tro q.../* 注释 */s ret = ..SaveDetail()i ret < 0 tro q...tc
}ClassMethod SaveMain()
{...
}ClassMethod SaveDetail()
{...
}
陷阱
- 严格禁止陷阱内部报错导致死进程。
反例:
/// d ##class(M.M87).Save()
ClassMethod Save()
{s $zt = "Error"Errors color = redq $ze
}
正例:
/// d ##class(M.M87).Save()
ClassMethod Save()
{s $zt = "Error"Error// 禁止写业务逻辑q $ze
}
- 如果类为
Not ProcedureBlock
,陷阱名称统一为Err + 方法名
。
反例:
ClassMethod Save()
{s $zt="Save"...
Save...
}
正例:
ClassMethod Save()
{s $zt="ErrSave"...
ErrSave...
}
- 默认类陷阱名称统一为
Error
,注意通用陷阱写法。
ClassMethod CommonZtrap() As %String
{s $zt = "Error"// todo q ""
Errors $zt = "" /* 避免死循环 */i $tl >0 tro /* 避免开放性事务 */lock /* 避免开放锁 */q $ze
}
格式
- 方法大括号一律换行显示。
反例:
SetDispEvent(){}
正例:
SetDispEvent()
{}
- 以下符号添加空格,美观代码,
=
、+
、-
、*
、/
、_
、:
左右加空格,,
之后加空格 。
反例:
GetName(hour,number,year)
{s name=“yaoxin”s day=hour*numbers sub=$o(^IRIS("DATE",day,hour,""))
}
正例:
GetName(hour, number, year)
{s name = “yaoxin”s day = hour * numbers sub = $o(^IRIS("DATE", day, hour, ""))
}
- 方法内命令行均采用一个制表符
tab
缩进,宽度为四个空格宽度。注意是一个tab
键,而不是按四次空格,可在studio
设置(默认为4)
反例:
GetName(hour,number)
{ s name=“yaoxin”s day=hour*numbers sub=$o(^IRIS("DATE",day,hour,""))
}
正例:
GetName(hour, number)
{s name = “yaoxin”s day = hour * numbers sub = $o(^IRIS("DATE", day, hour, ""))
}
SQL
语句一行5
个字段。并且换行后3
个tab
键为准。逗号在每行行末,不要带入下行开始。因为一行字符书不超过120
个,即一屏。
注意:sql
命令全部统一小写。
反例:
ClassMethod InsBox(str As %String) As %Library.String
{&SQL(Insert Into DHC_PHBox (PHB_No, PHB_Num, PHB_Status, PHB_FLoc_Dr,PHB_TLoc_Dr,PHB_UserCreate_Dr,PHB_DateCreate, PHB_TimeCreate, PHB_PrintFlag, PHB_Remark) values(:boxNo, 1, :status, :fromLocID, :toLocID,:userID, :date, :time, "Y", :remark))q SQLCODE
}
正例 insert
:
ClassMethod InsBox(str As %String) As %Library.String
{&SQL(insert into DHC_PHBox (PHB_No, PHB_Num, PHB_Status, PHB_FLoc_Dr, PHB_TLoc_Dr,PHB_UserCreate_Dr, PHB_DateCreate, PHB_TimeCreate, PHB_PrintFlag, PHB_Remark) values(:boxNo, 1, :status, :fromLocID, :toLocID,:userID, :date, :time, "Y", :remark))q SQLCODE
}
正例 update
:
ClassMethod UpdMenu(arg...) As %Library.String
{&sql(update CT.IMP.Menu set CIM_Name = :name, CIM_Path = :path, CIM_Component = :component, CIM_Icon = :icon, CIM_OrderNum = :numCIM_Status = :status,where ID = :ID)q SQLCODE
}
正例 delete
:
ClassMethod DelMenu(arg...) As %Library.String
{&sql(delete BS_PHA_IN.BarCode where ID = :ID)q SQLCODE
}
- 单行字符串拼写最多
5
个字段。因为一行字符书不超过120
个,即一屏。
反例:
ClassMethod GetString(str As %String) As %Library.String
{s str = first _ second _third _ fourth _ fifth _six
}
正例:
ClassMethod InsBox(str As %String) As %Library.String
{s str = $lb("first", "second", "other", 4, "71")s str = str _ $lb("y", "x", "what", "apple", "sum")s str = $lts(str, "^")w str
}
- 禁止用同一变量后加数字累加。
反例:
ClassMethod GetString(str As %String) As %Library.String
{s str1 = first _ second _ third _ fourth _ fifth s str2 = sixs str = str1 _ str2
}
正例:
ClassMethod GetString(str As %String) As %Library.String
{s str = first _ second _ third _ fourth _ fifth s str = str _ six
}
- 获取多返回值用数组
%ArrayOfDataTypes
或JSON
点语法或其他对象数组,不建议使用字符串拼接形式。
反例:
ClassMethod GetPatLocDesc(prescNo)
{s str = wardID _ "^" _ wardLocDR _ "^" _ patLocDesc q str
}
正例:
ClassMethod GetPatLocDesc(prescNo)
{s array = ##class(%ArrayOfDataTypes).%New()d array.SetAt(wardID, "wardID")d array.SetAt(wardLocDR, "wardLocDR")d array.SetAt(patLocDesc, "patLocDesc")q array
}
正例:
ClassMethod GetPatLocDesc(prescNo)
{s obj = {}s obj.wardID = wardIDs obj.wardLocDR = wardLocDRs obj.patLocDesc = patLocDescq obj
}
- 禁止系统命名混搭方法中出现
s
和set
统一用命名缩写方式。
反例:
ClassMethod GetPatLocDesc(prescNo)
{s str = “wardID”set patLocDesc = “病区”do ..GetName()q str
}
正例:
ClassMethod GetPatLocDesc(prescNo)
{s str = “wardID”s patLocDesc = “病区”d ..GetName()q str
}
- 禁止命令出现大小写,统一小写。
反例:
ClassMethod GetName(userID)
{s name=“yaoxin”S age=30
}
正例:
ClassMethod GetName(userID)
{s name = “yaoxin”s age = 30
}
- 尽量使用对仗词。
add/remove
open/close
get/set
start/end
insert/delete
show/hide
lock/unlock
first/last
next/previous
old/new
- 禁止
{}
和.
同时出现,推荐用使用块级语法,抛弃使用点语法。并且括号要对齐。
反例:
ClassMethod GetName(userID)
{i flag="yx" d.i other = "other"{s name = “other” }.s name = "yx"
}
正例:
ClassMethod GetName(userID)
{if flag="yx" {if other = "other" {s name = “other” }s name = "yx"}
}
- 如果
if
语句只有一行,建议使用三元运算符。所有if
语句都要换行写,即使只有一行。
反例:
i name="yx" s age=30
e s age=0
正例:1
i name = "yx" {s age = 30
} else {s age = 0
}
正例:2
s age = $s(name = "yx" , 1 : 0)
if
嵌套不宜过多,建议不超过3层。
反例:
i name = "yx" d
.s state = 30
.i gender = "男" d
..s state = 20
..i age = "年轻人"
...s state = 10
e d
.s state =0
正例:用策略模式或状态模式封装。
- 多级
if else
考虑用@case
替换。
反例:
i day =1 d
.s desc = "Monday"
e i day =2 d
.s desc = "Tuesday"
e i day =3 d
.s desc = "Wednesday"
正例:
$CASE(day,1:"Monday",2:"Tuesday",3:"Wednesday",4:"Thursday",5:"Friday",6:"Saturday",7:"Sunday",:"entry error"
)
- 与或逻辑运算统一使用
&&
、||
,禁止使用其他&
、!
、,
。
反例:
s firstName = "Yao"
s lastNmae = "Xin"
if firstName = "Yao",lastNmae = "Xin"
.w "true",!
e d
.w "false",!
正例:
s firstName = "Yao"s lastNmae = "Xin"i (firstName = "Yao")&&(lastNmae = "Xin") {w "true",!} else {w "false",!}
- 块级语法命令要全拼。例如
for
,if
命令在块语法中不要缩写,这样语义更强。
反例:
ClassMethod Login()
{s info =""f s info = $o(^IRIS("info", info)) q:info="" d.s flag = $p(^IRIS("info", info), "^", 1).i flag = "1" d..// todo
}
正例:
ClassMethod Login()
{s info = ""for {s info = $o(^IRIS("info", info))q:(info = "")s flag = $p(^IRIS("info", info), "^", 1)if (flag) {//to do }}
}
- 后置表达式要加括号,并且等号两侧加上空格。保持风格统一。
反例:
q:info=""
正例:
q:(info = "")
空行
- 方法与方法之间进行空行隔断。(1个空行)
反例:
Method GetName()
{...
}
Method GetAge()
{...
}
正例:
Method GetName()
{...
}Method GetAge()
{...
}
- 空行用来分割功能相似,逻辑内容,意思相近的代码片段,使程序布局更加清晰。
反例:
ClassMethod Execute(params)
{s $zt="ErrExecute"s prescNo = $p(params, ..#Del, 1)s exeCode = $p(params, ..#Del, 2) s userID = $p(params, ..#Del, 3)s locID = $p(params, ..#Del, 4)TSTARTs mExecute = ##class(PHA.DEC.MOB.Execute).%New(prescNo, exeCode, userID, locID)s ret = mExecute.Execute()i ret '= 0 TROLLBACKq:(ret '= 0) ..RetFail(ret)TCOMMITs rows = ..GetPrescDetail(prescNo)s objectJson = ..GetPrescData(prescNo)s objectJson.rows = rowsq ..RetObject(objectJson)
ErrExecuteq ..RetFail($ze)
}
正例:
ClassMethod Execute(params)
{s $zt="Error"s prescNo = $p(params, ..#Del, 1)s exeCode = $p(params, ..#Del, 2) s userID = $p(params, ..#Del, 3)s locID = $p(params, ..#Del, 4)tss mExecute = ##class(PHA.DEC.MOB.Execute).%New(prescNo, exeCode, userID, locID)s ret = mExecute.Execute()i ret '= 0 TROLLBACKq:(ret '= 0) ..RetFail(ret)tcs rows = ..GetPrescDetail(prescNo)s objectJson = ..GetPrescData(prescNo)s objectJson.rows = rowsq ..RetObject(objectJson)Errorq ..RetFail($ze)
}
- 基于第2点,空行之前添加行注释也要空行,并且行注释
/* 规则 */
。
- 注意:
*
空格的位置。
反例:
ClassMethod Execute(params)
{s $zt="ErrExecute"s prescNo = $p(params, ..#Del, 1)s exeCode = $p(params, ..#Del, 2) s userID = $p(params, ..#Del, 3)s locID = $p(params, ..#Del, 4)TSTARTs mExecute = ##class(PHA.DEC.MOB.Execute).%New(prescNo, exeCode, userID, locID)s ret = mExecute.Execute()i ret '= 0 TROLLBACKq:(ret '= 0) ..RetFail(ret)TCOMMITs rows = ..GetPrescDetail(prescNo)s objectJson = ..GetPrescData(prescNo)s objectJson.rows = rowsq ..RetObject(objectJson)
ErrExecuteq ..RetFail($ze)
}
正例:
ClassMethod Execute(params)
{s $zt="Error"/* 获取入参 */s prescNo = $p(params, ..#Del, 1)s exeCode = $p(params, ..#Del, 2) s userID = $p(params, ..#Del, 3)s locID = $p(params, ..#Del, 4)/* 执行方法 */tss mExecute = ##class(PHA.DEC.MOB.Execute).%New(prescNo, exeCode, userID, locID)s ret = mExecute.Execute()i ret '= 0 TROLLBACKq:(ret '= 0) ..RetFail(ret)tc/* 获取json */s rows = ..GetPrescDetail(prescNo)s objectJson = ..GetPrescData(prescNo)s objectJson.rows = rows/* 返回json */q ..RetObject(objectJson)Errorq ..RetFail($ze)
}
- 事务首尾先后一定要加空行或注释,代表强调。
反例:
Method SaveSomething(params)
{s ret = $$$NOts...//to dotcq ret
}
正例:
Method GetName()
{s ret = $$$NOts...//to dotcq ret
}
注释
- 句首注释用
/* */
,句尾注释用//
,头注释用///
,注意各类注释后应跟空格
。
反例:
// desc: 获取名称
///Input: 用户ID
ClassMethod GetName(userID)
{//获取参数s userID = $p(params, "#", 1) ;用户ID
}
正例:
/// desc: 获取名称
ClassMethod GetName(params)
{/* 获取参数 */s userID = $p(params, "#", 1) // 用户ID
}
- 避免无意义注释,尽量用规范的代码命名语言去描述。不要浪费大量时间在毫无意义的注释上。简明扼要,不要啰嗦,注释应当画龙点睛。
反例:
/// Description: 获取名称
/// Input: 用户ID
ClassMethod GetName(userID)
{}
正例:无须注释。
ClassMethod GetName(userID)
{}
- 所有类加上创建者和日期,创建者应为姓名的全拼,避免出现
yx
等简写或其他英文名,并简易说明类用途。
反例:
Class IRIS.MOB.API Extends IRIS.MOB.Biz
正例:
/// desc: 煎药室接口
/// author:yaoxin
/// date:2022-08-12
Class IRIS.MOB.API Extends IRIS.MOB.Biz
- 避免错误注释误导。可能由于复制过来方法,没有改注释。这样的注释后期开发人员困惑性极大。
反例:
/// Description: 获取年龄
/// Input: 科室ID
ClassMethod GetName(userID)
{}
正例:
ClassMethod GetName(userID)
{}
- 方法的完整注释,关于接口中的方法以及存储数据核心方法(如门诊发药),应给与完整注释以及修改记录等。
/// desc: 住院是否存在未退药,提前退费已退
/// author: name
/// date: 2022-09-12
/// params: name - 姓名, age - 年轻
/// retrun: 输出说明
/// version: V7~V8.3+
/// caller: 医生,护士,计费
/// modify: 增加急诊留观判断, 2020-02-01, name
/// debug: w ##class(XXX).XX(xxx)
- 类和方法注释 保持对齐公正。
反例:
/// desc: 住院是否存在未退药,提前退费已退
/// author: name
/// date: 2022-09-12
/// params: name - 姓名, age - 年轻
/// retrun: 输出说明
/// version: V7~V8.3+
/// caller: 医生,护士,计费
/// modify: 增加急诊留观判断, 2020-02-01, name
/// debug: w ##class(XXX).XX(xxx)
正例:
/// desc: 住院是否存在未退药,提前退费已退
/// author: name
/// createDate: 2022-09-12
/// params: name - 姓名, age - 年轻
/// retrun: 输出说明
/// version: V7~V8.3+
/// caller: 医生,护士,计费
/// modify: 增加急诊留观判断, 2020-02-01, name
/// debug: w ##class(XXX).XX(xxx)
M通用版代码规范 - 持续更新相关推荐
- 【第十一届泰迪杯数据挖掘挑战赛】A 题:新冠疫情防控数据的分析 思路+代码(持续更新)
[第十一届泰迪杯数据挖掘挑战赛]A 题:新冠疫情防控数据的分析 思路+代码(持续更新) 问题背景 解决问题 代码下载 数据分析 Task1 Task2 Task 3 问题背景 自 2019 年底至今, ...
- HDU杭电OJ经典100题2000-2099_Java版详细题解(持续更新)
今年寒假打算用Java把杭电2000-2099全部AC(现在持续更新),如下是题目链接,之后是我的题解,全部做完后我会把所有AC的题解打包上传的 题号 题名 题号 题名 2000 ASCII码排序 2 ...
- FC金手指代码大全·持续更新-亲测可用-FC 经典游戏完整可用的金手指大全---持续更新,偶尔玩玩经典回味无穷,小时候不能通关的现在通通通关一遍
FC 经典游戏完整可用的金手指大全-持续更新,偶尔玩玩经典回味无穷,小时候不能通关的现在通通通关一遍 2021年5月11日更新: 每次翻金手指一些垃圾小网站标题党吸引进去吓一大堆木马什么也没有,什么x ...
- 商业数据分析模型及其核心Python代码_持续更新
商业数据分析模型_持续更新 一.AARRR模型 二.PEST模型 理论 医美行业应用案例 三.RFM模型 理论 Python实战_核心指标计算 四.SWOT模型 五.5W1H模型 六.流程拆解法 七. ...
- 【剑指offer】java版题解(持续更新)
本文为刷[剑指]备战校招的过程,持续更新 备战虽晚但卷,共勉! 目录,按刷题时间排序 斐波那契数列 用两个栈实现队列 二维数组中的查找 包含min函数的栈 从尾到头打印链表 反转链表 复杂链表的复制 ...
- QT 实用代码片段 (持续更新)
由于项目需要开始转型学习C++,GUI使用QT进行开发,开发过程中踩了不少坑,但是也积累了些宝贵经验,在这儿记录一下,希望能帮到需要的朋友. 1.设置无边框对话框 //设置对话框属性 setWindo ...
- 12306抢票系统(框架+代码)- 持续更新
文章目录 一.框架展示(后续将提供源码) 二.界面展示 三.过程及结果展示 12306抢票系统(登录功能-二维码+账号密码)---------- 点击跳转 一.框架展示(后续将提供源码) 首先在 ...
- 数据结构(严蔚敏C语言版)代码实现持续更新中
文章汇总: 线性表: 线性表的顺序表示和实现 线性表的链式表示和实现 静态链表的表示和实现 栈: 顺序栈--栈的顺序表示和实现 链栈--栈的链式表示和实现 队列: 链队列--队列的链式表示和实现 顺序 ...
- Linux系统各发行版镜像下载(持续更新)---download
http://www.linuxidc.com/Linux/2007-09/7399.htm Linux系统各发行版镜像下载(2014年10月更新),如果直接下载不了,请使用迅雷下载.并且注意,我的下 ...
最新文章
- cmd中实现scott的解锁和开锁以及授予dba权限
- Zookeeper之javaAPI的使用
- java redis 网络断开_Redis长时间连接后自动断开
- python爬虫入门代码-如何开始写你的第一个爬虫脚本——简单爬虫入门!
- python怎么安装到d盘-python必须装在c盘吗
- IntelliJ Idea学习笔记006---Idea左侧栏不显示目录结构
- html table 显示最后一条,漂亮CSS表格(Table),最后一行是汇总行【实例】
- redis数据类型之ZSet
- roller java,月光软件站 - 编程文档 - Java - 修改ReadMorePlugin.java,使其支持中文标题(roller webblog)...
- Python 数据可视化学习笔记 之高维数据可视化及其方法
- 画出psnr_计算图像的峰值信噪比PSNR以及均方根误差MSE
- 空气质量监测管理系统
- 数学分析教程(科大)——1.11笔记+习题
- python怎么算二元一次方程_Python简单实现二元一次方程求根
- 武汉音乐学院计算机免修成绩,教务处
- 01 计算机网络概念
- Calendar获取当前日期,或前几天,或后几天的日期
- 集群服务器中定时任务多次执行的解决方案
- 苹果手机聊天记录恢复方法有哪些?这2个恢复技巧值得收藏
- 武汉轻工大学计算机学院宿舍,武汉轻工大学有几个校区及校区地址 哪个校区最好...