302Soft—302软件技术联盟

ASP.NET / C# / PowerBuilder 技术交流
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

PB编程规范

Posted on 2007-01-09 01:38  寒夜听雨  阅读(1487)  评论(0编辑  收藏  举报

编程规范(PB)

 

1         简介

1.1       简介

这个文档描述了用于编写稳定、可靠的PowerBuilder应用程序的一些标准、约定和准则。 他们基于合理的,经过证实的一些使代码容易理解、 维护和增强的软件工程的原则。另外,遵循这些标准,你作为一个PowerBuilder程序员的生产力将有一个显著的提高。一些经验证明,花时间在项目的开始写出高质量的代码,可以使在后来的开发过程中容易修改它,从而事半功倍。最后,遵循这一系列编码规范,可以使一个开发团队更好地保持一致性,最终必将极大地提高团队的生产力。

 

1.2       最初的准则和最终的准则

当你无法找到一些你需要的原则或准则时,或者它们很明显地不适用,或者其它的一些情况下,请使用常识,按照一些基本的原理去作。这个原则凌驾于其他原则。

2         命名规范

2.1       一般性约定

1.使用英文或汉语拼音的全称去准确地描述各种对象、变量 例如,ls_UserName (用户名) ldc_GrandTotal(总计)等等。尽管x1,y1这样的名称很容易拼写,因为它们很短,但是他们不可能明确地提示名称的含义,将导致代码难以理解、维护和改进。

2.使用大小写混合的方式命名

3.以合适的方式使用缩写 例如ll_RownNmber,简写为ll_RowNum是可以理解的,但是li_ReturnCode简写为li_rc就不一定被别人看懂,所以应该以尽量保守的态度使用缩写,在更多的时候使用全称,或者建立常用缩写的对照表。

4.避免太长的名称,尽量限制在15个字母以内 长名称虽然很容易懂,但特别长将导致拼写时经常出错。

5.不要在第一个字母和最后一个字母使用下划线

6.保持命名的一致性。相关的东西应给以相关的名字,以说明他们的关系和差异

2.2   具体约定

2.2.1        对象命名规范

<前缀>_名称

前缀

说明

m

菜单(Menu)

n

标准用户对象(Standard class user object)

n_cst

定制用户对象(Custom class user object)

u

可视用户对象(Visual user object)

d

数据窗口(Datawindow)

w

窗口(Window)

s

全局结构(Global structure)

 

注:名称为英文,新建对象必须加注释(菜单对象可例外)。一般情况下,菜单对象的名称与其所属窗口的名称一致。

 

例子:

w_master , m_master , d_cig_cd

u_tvs is the TreeView visual user object

u_dw is the DataWindow visual user object

n_cst_dwsrv is the custom class user object for DataWindow services

n_tr is the transaction standard class user object and is in the extension level

2.2.2        变量范围命名规范

<范围><数据类型>_变量名

范围:

范围

说明

a

事件或函数的参数(Argument to an event or function)

g

全局变量(Global variable)

i

实例变量(Instance variable)

l

局部变量(Local variable)

s

共享变量(Shared variable)

 

 

对于标准数据类型:

数据类型

说明

a

Any

blb

Blob

b

Boolean

ch

Character

d

Date

dt

DateTime

dc

Decimal

dbl

Double

e

Enumerated

i

Integer

l

Long

r

Real

s

String

tm

Time

ui

UnsignedInteger

ul

UnsignedLong

 

例子:

 as_unitcode  表示事件或函数的输入参数,string类型

 idc_val           表示实例变量,decimal 类型

 li_row            表示局部变量,integer 类型

 gd_firstday    表示全局变量,date类型

 

对于常用参照数据类型(reference variables):

 数据类型

说明

ds

DataStore

dw

DataWindow

dwc

DataWindowChild

dwo

Dwobject

lvi

ListViewItem

mm

MailMessage

mr

MailRecipient

ms

MailSession

str

Structure

tr

Transaction

tv

TreeView

tvi

TreeViewItem

w

Window

 

例子:

datastore               lds_unit    

DataWindowChild   ldwc_cig  

window                        lw_code

 

注:

1) 尽量避免使用全局变量。

2) 全局变量和实例变量必须加注释(说明该变量在何处设置和使用);重要的局部变量加注释

4)全局变量使用具有说明性(名字足够长)的名字,局部变量用短名字

5)按常规方式使用的局部变量可以采用极短的名字。例如:用ij作为循环变量

例如:在windowopen()事件中对统计日期id_date赋值,在dw_unit.itemchanged()cb_ok.clicked()中使用,则定义如下

//Set: open

//Use: dw_unit.itemchanged, cb_ok.clicked

Date        id_date   //统计日期

 

2.2.3        函数命名规范

<前缀>_ FunctionName

前缀

说明

wf

窗口函数

of

对象函数

f

全局函数

 

例子:wf_GetTime, of_ GetTime, f_ GetTime

注:不使用全局函数(使用用户对象封装);函数名采用动作性的名字,后面可以跟着名词

 

2.2.4        窗口中控件命名规范

<前缀>_名称

 

前缀参照PowerBuilder的缺省规定

对于下拉数据窗口,使用如下命名方式:d_dddw_ + name

另外,如果同类控件在窗口中出现两次以上,名称必须为英文,不能是数字。

例如:在同一窗口中有两个CommandButton,不能命名为cb_1cb_2,必须是有意义的名称,如cb_okcb_cancel

 

2.2.5        数据库对象命名规范

数据库对象包括表、视图、触发器及存储过程等

库名:           英文前三个字母

表命名:        小写,应尽量用英文,也可用拼音,视情况而定;表名前加比较短小的业务名称,推荐用两位汉语拼音简写 (例如,储运,cy) ;主从表的命名,主表名_s_s1_s2;代码表后面加_cd;表名尽量短小精焊

视图命名:           v_名称,名称为表名或主要表名

触发器命名:       ti_表名 (insert trigger)

td_表名 (delete trigger

tu_表名 (update trigger)

tui_表名,tud_表名,tid_表名,tuid_表名 (复合 trigger

存储过程:           sp_名称

列名:          小写,连接符使用下划线;字符型尽量用varchar,尽量加长。

常用列名或列名后缀:

代码:_cd;无意义:_id;名称:_nm;金额:_mny;数量:_qty;日期:_dt;标志:_mark

人:_er_or;类型:_tp;审核人:verifier;部门:_dept;编号:_no;计量单位:jldw;大小:sz;重量:wg;备注:rem;率:_rate;制单人:maker;时间:_tm;开始时间:start_dt;结束时间:end_dt;批号:bat_no;周期:cycle

3         表达式和语句

1.       使用缩行显示程序的结构。采用一种一致的缩行风格,是使程序呈现出结构清晰的最省力的方法

2.       使用表达式的自然形式。例如:

IF (Not (ldc_BlockId < ldc_ActBlks) Or Not (ldc_BlockId >= ldc_ActBlks)) Then

在上面的语句中两个测试都用到了否定,而他们是不必要的,应该改变关系运算符的方向,是测试变成肯定的:

IF ((ldc_BlockId >= ldc_ActBlks) Or (ldc_BlockId < ldc_ActBlks)) Then

    3.  用加括号的方式排出二义性。括号表示分组,即使有时并不必要,加了括号也可能把意图表示的更清楚,上面的例子中,内层括号就不是必须的。

4.  分解复杂的表达式。

5.  当心副作用。 ++ 这一类的运算符具有副作用,它们除了返回一个之外,还将隐含地改变变量的值。

4         界面设计

4.1       一般性约定

界面设计是软件设计中很重要的一部分,一些优秀的系统大都拥有优秀的界面设计,一些大公司的界面设计往往精确到像素。但是,很多人对优秀界面的理解就是“漂亮”甚至说“花哨”,而忽视了更重要的东西,这就有些不妥了。那么一个优秀的设计应该具有什么样的特征呢?

 

1功能性 界面设计必须符合功能的需要,这个是最重要的,界面是用户使用系统的途径,优秀的界面必须与功能的需求相统一。应该重点突出,结构清晰,布局具有整体感。用类似winamp的用户界面来处理数据应用的界面,就有点不伦不类了。

2导航   优秀的界面应该给用户舒适的导航,用户可以很容易找到相应的功能,或者可以引导用户正确的操作,避免错误。重点的元素放在醒目的地方。

3友好   尽量不要出现用户看不明白的提示、专业术语或错误信息。

4操作性 一个优秀的界面设计,必须具有良好的操作性,符合大多数人的操作习惯,对于特殊应用,可快速操作也很重要。

5时尚性 密切注意流行界面的发展方向,当然也不是盲目跟从。比如win98时代就不要再开发win32风格的界面了。

 

那么开发时应注意什么呢?

1、整个系统应该风格统一,不要前后矛盾,比如前一个窗口中红色代表错误,在接下来的提示中又用红色来表示重要信息。

2、不要使用让用户产生歧义的图标、图形或文字,比如有人在退出按钮上写上逃离,又如,保存按钮写就这样吧等等。。

3、尽量不要使用activeskin之类的换肤软件,其一这些皮肤其实并不美观,其二增加了系统出错机会,加大系统开发复杂度。

4、合理的结构设计,可能的情况下,将界面设计与业务逻辑独立开来,尽量不要将业务逻辑写到界面之中,比如有人在确定按钮里写了几百行的代码,所有功能都在里面了。

5、导航深度不要超过3层,有的设计往往要好几级菜单下才能找到相应的功能。还有的功能必须要层层打开n个窗口后,才在一个角落里发现打开它的按钮。

6、不要使用太扎眼的元素,比如颜色,线条等。例如一个使用亮绿色的提示窗口会让用户睁不开眼睛

7、窗口元素布局要整齐划一,比如即使用不了那么长的文本框,也要使它与上面的文本框一样长

8、不要在界面上出现可有可无的东西,有人用了一半的窗口面积描述这个窗口各个按钮的使用方法,此举纯属画蛇添足,因为一个熟练的用户闭着眼睛都知道下一步该按哪个键,当然面向大众的软件例外。

 

。。。。。。。

4.2    具体约定

1、  界面(包括WindowDataWindow)应在800*600分辨率下设计(同时应支持其它分辨率);整个系统一般使用9号宋体,个别情况(如标题)用大字体(14号宋体)

2、  同一窗口界面中颜色不能超过4

3、  DropDownDataWindow的风格用Tabular,白底黑字,下拉后不能显示所有记录时,必须加垂直滚动条;grid 风格的DataWindow不要用下凹和灰底,在"Summary" 段加合计,显示共多少条记录等信息

4、  CommandButton 不能出现在左面和上面,不要紧贴窗口边界;普通CommandButton大小为352*92当与SingleLineEdit等其它控件合用时(如:在SingleLineEdit输入查询,在右面有一查询按钮),可以放在上面,并用Group围往

5、  不能含有无用的隐藏控件;不要用隐藏的datawindow, datastore代替

6、  MDI风格设计,除主窗口上的菜单可带有toolbar外,其他窗口少用toolbar

7、  多个RadioButton(其中一个必须为Checked)和CheckBoxGroup围住,点击后不能出现打开窗口等类似按钮的动作

8、  TabPage要有图标

10、所有的日期用yyyy-mm-dd格式

11DataWindowBorderStyleStyleLowered,主细窗口之间的距离不超过20 PBU,宽高的设置应尽量避免横竖滚动条的同时出现

12、窗口中的左上角和右下角的控件距窗口边界的距离为X64PBUY56PBU14Pixels

13、              FreeForm类型的录入数据窗口,TextColumn的高度为56 PBU,一对TextColumn,之间的距离为0Text后加单字节冒号“:”,右对齐Column加下划线,左对齐;不可录入的TextColumnTaborder0,颜色为Navy

14、              Grid类型的录入数据窗口,HeaderDetail的高度为84;标题不加粗,中间对齐;最左列加“行号”(如果无行号字段,用计算域getrow()),中间对齐;所有数字列右对齐,其它列左对齐,都为白底黑字;小计、合计的颜色为Navy,中间对齐,放在下面。不可录入的Grid数据窗口,去掉MouseSelection属性,否则点中字段后会出现黑块

15、对于不用做主细录入的Grid型数据窗口,标题和行号可以用灰底凸起形式

日期字段用EditMaskyyyy-mm-dd),不用下拉日历,否则会出现时分秒

16、所有菜单的后面必须有加速键,加速键为半角圆括号括起的大写英文字母,同级菜单中不能用相同的加速键。第一个菜单中的最后一个菜单项是退出系统[Ctrl+X]上面为横线

5          注释约定

5.1       注释的一般性约定

1、注释使你的代码更整洁 你为你的代码写注释使为了使你的代码更容易被你、你的合作者、以及后来参与这个项目的任何其他程序员更好的理解你的代码。

2. 保持注释的简单 一些好的注释是简单的。你没有必要象写书一样的写注释,你只要提供充分的信息使别人理解你的代码就可以了。

3、在注释中要写明为什么要写这段代码,而不仅仅是这段代码在做什么 例如

§ If ldec_ GrandTotal >= 1000.00 Then

§ ldec_GrandTotal = ldec_GrandTotal * 0.95

§ End If

§           上面的代码显示总计大于1000时,将总计乘以0.95,为什么要这样做? 是否有商业规则要求大额合同可以得到折扣?这种折扣是有时间限制的还是一直沿用?或者是这个程序员的慷慨大方?除非在某个地方有这方面的说明,否则你不可能明白。

5.2       注释的具体约定

5.2.1        函数的注释约定

函数注释风格常常是函数是否易于理解、维护和改进的关键因素。

每个函数前需要有如下格式的函数说明

 

//////////////////////////////////////////////////////
//
函数名: of_init
//
//
访问权: public

//

// 描述: ini文件的某个段中读取值来初始化对象的属性 
// 
         如果没有取到值,属性被赋值为空字符串''
//
//
参数:
// as_inifile  
          函数要读取信息的ini文件的名称
// as_inisection     ini文件的段名
// 
//
//
返回值: integer
// 1 
    正确
// -1    有错误发生
//
//
作者:闫修华         时间:2002-09-12

//
///////////////////////////////////////////////////////
//
//
修改
//
//
作者:闫修华         时间:2002-09-25

// 原因:
//
//////////////////////////////////////////////////////

 

除此之外,还可能包含如下信息:

·  如果函数内部调用了其他自定义函数,应予以说明。

·  如果该函数只能与其他函数配合使用,请注明与之有关联的其他函数

·  如果函数有缺陷,请予以注明

·  如果函数隶属于其他对象,例如窗口函数、用户对象函数等,可能在函数中改变此        对象的一些属性,此时需要在函数中予以说明。

·  在函数的注释中,不仅应该描述函数做了什么,还应包含函数为什么要这样做。以  便别人很快理解你的编程思路。

5.2.2        自定义事件的注释约定

事件需要下面有类似的说明:

 

//////////////////////////////////////////////////////

//

// 事件名: ue_deleterow

//

// 描述: 删除当前行或选中行

//

// 参数表: (空)

//

// 返回值: integer

// 1     成功删除行

// 0     行没有被删除

// -1    发生错误

//

// 作者:闫修华         时间:2002-09-12

//

//////////////////////////////////////////////////////

// 修改:

//

// 作者:闫修华         时间:2002-09-25

// 原因:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

//

//////////////////////////////////////////////////////

除了事件应该有的注释之外,自定义事件的注释还应该包括:

·             为什么要定义这个事件

·             何时触发

·             参数说明  

6         书写整洁的代码的技巧

  • 常量全部大写
  • 声明变量时,

声明变量时,每个变量占一行,后面加注释来描述它的用途。使用tab分隔变量类型和变量名,以保证上下两行的排列整齐,如:

long      ll_CurrentRow    //当前行号
string    ls_Name          //名字

而不是:
long ll_CurrentRow    //当前行号
string ls_Name   //名字

  • 不可以以st_1,dw_1,cb_1来命名对象或控件
  • 书写代码的过程中使用分段和缩进
  • 使用空白 例如:

li_ModifiedNumber + li_DeletedNumber = li_Total,

不要写成

li_ModifiedNumber+li_DeletedNumber=li_Total

  • 使用Tab键而不是空格键来缩排循环中的代码及其他复合语句,以显示包含关系。
  • 在所有运算符(+-*/)及赋值动词(=)的前面和后面都要加上一个空格,
    并且在函数参数表中的每一个逗号后面也要加一个空格。
    如:

string ls_Value
ls_Value = gf_GetSystemSet("1999/2/23", "system") 
dw_maint.SetItem(Row, Col, ls_Value)

而不是

string ls_Value
ls_value=gf_getSystemSet("1999/2/23","system") 
dw_maint.SetItem(row,Col,ls_value)

  • 数据库命令(例如,INSERTSELECT以及DECLARE CURSOR)应全部大写,
    而域名则小写并且PowerBuilder约束变量应使用与普遍变量同样的约定。
  • Powersoft的函数和命令的每一个单词的第一个字母都应该大写或全部小写
    (例如,If,RightTrim(),而不是IF, RIGHTTRIM())。
  • 在行延续时应把连接标记(例如AND+)放在行的末尾而不要放在下一行的开始处。
  • 单行结构的语句应分解为多行:

If ll_Rows > 6 Then
    dw_report.Retrieve()
End If

而不用下面的写法:

If ll_Rows > 6 Then dw_report.Retrieve()

7       遵循30秒原则

任何程序员可以在30之内读懂你写的一段代码。如果不能,说明这段代码太长了,应该把其中的一部分封装起来,写成一个函数。

8         修改规范

8.1       增加代码

§           //added by闫修华 @2001-11-20    begin

§           //增加的原因(如果原因很明显,可以不写)

§    增加的代码……………

§           //added by闫修华 @2001-11-20    end

8.2       修改代码

§           首先将原来的代码注释掉

§           /*commented by闫修华 @2001-11-20 begin

§           修改原因

§           ………………

§           ………………

§           commented by闫修华 @2001-11-20  end*/

§           然后增加修改的代码

§           //new script added by闫修华 @2001-11-20  begin

§           修改的代码…………

§           //new script added by闫修华 @2001-11-20  end

8.3       删除代码

§           /*deleted by闫修华 @2001-11-20 begin

§           删除原因

§           删除的代码…………

§           deleted by闫修华 @2001-11-20 end */

 


Copyright(C) 2004-2007 302Soft-寒夜听雨 版权所有