蛙蛙推荐:VB开发规范讨论.doc

偶以前是搞VC的,近期接到一个任务维护一个旧的VB程序,是从VB4作起的,经历了VB4VB5VB6,可能是由于以前受限太多,所以现在有如下几点毛病(我认为是毛病,与VC做比较),请各位大侠指点:怎样做最正确、怎样做最适合我的情况

 

1、使用了很多、相当多的全局变量,并且很多是定义在Modules里面,生存期太长,并且容易发生命名冲突、交叉访问,没有保护级别,交叉使用了也难以发现;

 

2、变量命名不规范,很多如xpmypmxpm0ypm0一类的命名,难以记忆,同时VB6的辅助功能似乎也不够,鼠标指向某个变量时无变量类型、注释等信息显示;

 

3、辅助功能的另一个缺陷就是不支持鼠标中轴,上下翻页时托拽的好辛苦;

 

4、窗体和Modual命名也不规范,不知道能不能改名;

 

5、有个Main的入口和一个主FormMian调用Form后一直在后台循环,监视两个通讯口状态(据说是防止响应通讯事件的延迟),虽然使用DoEvents,但是CPU资源的占用一直是100%;在VC里常用的方法是使用一个辅助线程“等待”通讯事件,基本上不用担心响应延迟,这里似乎应该也可以这样做,不过水平有限,暂时还没查到相关资料;

 

6、需要兼容982K,不知道需要注意哪些方面?现在偶就知道Sleep98下不能使用;

 

7、绘图控件似乎只能操作Interge,而我需要Double操作,最少也是long吧……有效位数不能太少;

 

8、界面挺难看,没有色彩没有动态窗体,有些Form里使用的背景色灰度还不同;

 

9Project窗口里有太多Form,不知道如何把它们分门别类放置,Modules想来也会有类似情况;

 

10、只有个别几个结构类型,没有类,转换到类体系工作量似乎太大了,心里有点虚;

 

 

另外提几个问题:

1、不知道在FormP里定义的Private变量,如何给FormP调用的子FormS使用?

 

2、如果Form里定义了Public变量,Unload Form后哪些变量是否还存在?如果是其他类型呢?有的书上说PublicStatic一样,不理解……

 

3、无论在哪里自定义一个类型(结构)后,其他地方都可以使用它定义变量么?不需要C++里的头文件或者声明么?

 

4、如果把这个项目移植到VC.net是否实际:工作量会增加么?兼容性会受影响么?看一些资料提到VC.net的许多新特性,和C++越来越相似了,如可以赋初值(可以使用时才定义)、可以继承类(而不是实现接口)等,感觉蛮亲切的。

 

5、据说VB调用API容易引发错误,而且On Error无法捕捉到,所以易死机,不知道是否确有其事?

 

先问这么多了,各位大佬给诊诊吧,谢了先!

我一开始就主张重写,用VC重写,再要不就用VB.net重写,可惜头头不同意呀!

 

各位大佬,对诊下药可能过于烦琐,您就给我开几个健身的方子吧,比如用VB做项目比较好的习惯是怎样的:变量定义、生存期、保护级别、窗体和模块的关系等。

 

 

其实想开了这次维护虽然痛苦了点,但是真的体会到了文档、编程风格、设计模式等的重要性了,反正也不赶时间,我打算一边改写一边学习使用ROSE2K,如果有兴趣讨论ROSE的朋友可以MSN联系:rainee_my@hotmail.com

 

另外提几个问题:

1、不知道在FormP里定义的Private变量,如何给FormP调用的子FormS使用?

 

In FormP:

private m_sPage as string

 

friend property get Page() as string

Page=m_sPage

end property

friend property let Page(byval sPage as string)

m_sPage=spage

end property

 

In FormS:

FormP.Page=

 

2、如果Form里定义了Public变量,Unload Form后哪些变量是否还存在?如果是其他类型呢?有的书上说PublicStatic一样,不理解……

 

全局的public,private的应该都还在 Public static应该不一样,public应该可以被外部访问,static不可以

 

 

3、无论在哪里自定义一个类型(结构)后,其他地方都可以使用它定义变量么?不需要C++里的头文件或者声明么?

 

模块里声明的public type 是这样的

 

 

4、如果把这个项目移植到VC.net是否实际:工作量会增加么?兼容性会受影响么?看一些资料提到VC.net的许多新特性,和C++越来越相似了,如可以赋初值(可以使用时才定义)、可以继承类(而不是实现接口)等,感觉蛮亲切的。

 

不知道

 

5、据说VB调用API容易引发错误,而且On Error无法捕捉到,所以易死机,不知道是否确有其事?

 

应该捕捉不到,API应用不当造成非法操作是很经常地

多谢大家支持。

 

关于变量我经过测试总结了一点东西:

变量定义、生存期(作用域略)

 

过程级:

 

允许定义Dim或者Static两种方式,Dim的生存期仅在过程中,Static的生存期等于程序的生存期;

Static FunctionDim声明等同于Static

"

窗体级:

 

允许定义DimPrivatePublic三种方式,Dim Private

生存期从窗体产生到窗体Unload并且窗体名Set nothing为止,仅Unload而未设置Set Form nothing不能释放变量内存

"

模块级:

 

Dim PrivateGlobal Public

生存期等于程序的生存期;

"

类:未测试,应该同C++近似吧

"

注意事项:

 

仅过程级中可以定义Static类型;

常量、固定长度字符串、数组、自定义类型、断言等不得使用Public类型;

Form也应该看作一个特殊一点的class

 

至于private ,public ,global,dim ,我是这样理解的

 

global完全是用于兼容以前的vb4而保留的

我在写程序的时候从来不用的

模块级的边两都用private ,public,而不用dim

 

至于管理,一般都是

 

Project Folder

   |

   +--Form(Folder)

   +--Class(Folder)

   +--Module(Folder)

   +--Projects Relation Files(Like .vbp,.vbg)

   +--_Resource(Folder)

   |    |

   |    +--Cursor(Folder)

   |    +--Icon(Folder)

   |    |    +--16x16(Folder)

   |    |    +--32x32(Folder)

   |    +--Images(Folder)

   |

   +--_Documents(Folder) 

   |

   +--_History(Folder)

   +--_Release(Folder)

   |

   |

 

 

  以上仅供参考,一般都会吧_Document等放到上一层的Folder中,在此简单写了

楼主讲的问题正是困扰在下的问题,

 

与楼主不同的是,在下是今年才毕业学生,没有太多经验

 

而我的项目负责人,比我早一年毕业,很喜欢“修修补补”,

 

想在哪加变量就在哪加变量,想起什么名字就起什么名字,没有注释,也没有文档。

 

程序构架也从不与我商量,甚至不告知。丝毫不考虑我的感受。

 

很多东西都要靠我自己读源代码来消化体会。

 

经常会出现楼主讲的第一种错误:

1、使用了很多、相当多的全局变量,并且很多是定义在Modules里面,生存期太长,并且容易发生命名冲突、交叉访问,没有保护级别,交叉使用了也难以发现;

 

 

很多时候,讲起来我这种做维护的是比较卑贱的,但是我觉得如果我和他换个位子,

 

他未必能做得比我更好。

1、使用了很多、相当多的全局变量,并且很多是定义在Modules里面,生存期太长,并且容易发生命名冲突、交叉访问,没有保护级别,交叉使用了也难以发现;

 

尽量不要在Modules中定义全局变量,对确实需要的,加上注释。对常量,使用Const声明。如果一个From中的变量需要在其它From中调用,可以在这个From中声明一个Public变量,用FromName.变量的方式调用,可以解决命名冲突、交叉访问以及生存期太长(占用内存)的问题

 

2、变量命名不规范,很多如xpmypmxpm0ypm0一类的命名,难以记忆,同时VB6的辅助功能似乎也不够,鼠标指向某个变量时无变量类型、注释等信息显示;

 

VB有自己的命名规范,和C不太一样,如Dim intPos as integer,dim strName as string ,dim blnFlag as boolean等,即范围前缀(m,g)+数组前缀(a)+类型前缀(int,str ...)+变量名,如模块级字符型数组变量:mastrID,全局级整型变量:gintYear,过程级长整型变量:lngX。良好的命名习惯可以减少很多不必要的失误,另外,在FromModules的第一行加上option explicit(变量使用前必须声明)是一个非常好的习惯。变量、对象、控件的命名规范可以在MSDN中找到。

 

3、辅助功能的另一个缺陷就是不支持鼠标中轴,上下翻页时托拽的好辛苦;

 

这个有解决方法。

 

4、窗体和Modual命名也不规范,不知道能不能改名;

 

窗体以frm为前缀,模块以mdl为前缀,类模块以cls为前缀。工程建立后,可以改变窗体和模块的名称,但文件名不会改,想连文件名一起改过来,必须另存为。最好的办法是干脆新建一个窗体或模块,用规范的名字命名后把代码粘过来。

 

5、有个Main的入口和一个主FormMian调用Form后一直在后台循环,监视两个通讯口状态(据说是防止响应通讯事件的延迟),虽然使用DoEvents,但是CPU资源的占用一直是100%;在VC里常用的方法是使用一个辅助线程“等待”通讯事件,基本上不用担心响应延迟,这里似乎应该也可以这样做,不过水平有限,暂时还没查到相关资料;

 

涉及到具体代码,可以发上来大家讨论一下。

 

6、需要兼容982K,不知道需要注意哪些方面?现在偶就知道Sleep98下不能使用;

 

VB里有Sleep这个函数吗?

 

7、绘图控件似乎只能操作Interge,而我需要Double操作,最少也是long吧……有效位数不能太少;

 

不知道你说的哪个绘图控件,大家讨论一下。

 

8、界面挺难看,没有色彩没有动态窗体,有些Form里使用的背景色灰度还不同;

 

VB界面可以做得非常好看,而且也不会比VC麻烦。

 

9Project窗口里有太多Form,不知道如何把它们分门别类放置,Modules想来也会有类似情况;

 

好象没有别的方法吧,呵呵

 

10、只有个别几个结构类型,没有类,转换到类体系工作量似乎太大了,心里有点虚;

 

VB支持类,只不过不完全,比如不能重写构造函数,不能继承。

 

另外提几个问题:

1、不知道在FormP里定义的Private变量,如何给FormP调用的子FormS使用?

 

Private变量不能在别的窗体中调用

 

2、如果Form里定义了Public变量,Unload Form后哪些变量是否还存在?如果是其他类型呢?有的书上说PublicStatic一样,不理解……

 

Unload From后,From里的变量自然就释放了。demo001说的问题,实际是当你调用print from2.i时,from2已经被load了。也就是说调用一个From中的变量时,如果这个FROM没有被LoadVB会自动先Load它,demo001不妨在From_Load中写一行代码来验证一下。

 

3、无论在哪里自定义一个类型(结构)后,其他地方都可以使用它定义变量么?不需要C++里的头文件或者声明么?

 

必须在模块中声明为public

 

4、如果把这个项目移植到VC.net是否实际:工作量会增加么?兼容性会受影响么?看一些资料提到VC.net的许多新特性,和C++越来越相似了,如可以赋初值(可以使用时才定义)、可以继承类(而不是实现接口)等,感觉蛮亲切的。

 

楼主应该说的是VB.net吧?VB.net实际上和VB已经有很大区别了。不知道楼主的这个软件主要是做什么用的,如果包含较多的图形处理的话,还是用vb.net重写吧。VB.net在图形处理上与VB有本质上的区别。除此之外,VB大部分的语句和函数都可以在VB.net中使用,只不过感觉有点不伦不类,你可以用VB.netVB6升级向导试试,不过估计自己还是要做很多工作。

 

5、据说VB调用API容易引发错误,而且On Error无法捕捉到,所以易死机,不知道是否确有其事?

on error无法捕捉到API错误。VB调用API只要注意到变量类型的转换、内存的释放等几个地方就行了,没那么可怕的。

 

本人的一点经验,大家有兴趣共同讨论一下。

、如果Form里定义了Public变量,Unload Form后哪些变量是否还存在?如果是其他类型呢?有的书上说PublicStatic一样,不理解……

 

Unload From后,From里的变量自然就释放了。demo001说的问题,实际是当你调用print from2.i时,from2已经被load了。也就是说调用一个From中的变量时,如果这个FROM没有被LoadVB会自动先Load它,demo001不妨在From_Load中写一行代码来验证一下。

 

--------------------------------

 

楼主已经说了,Set nothing之后,才能完全被销毁,这个说法是对的

 

不管你

Set o=New Form2

o.show

还是

Form2.show

 

最后只有set nothing才能完全销毁,否则,你还是可以引用其公共变量

别人的代码的确是个头痛的事,尤其是改不规范的代码,如果工作量太大,我宁愿重写

 

VB.net中,Main函数仍然可以做为程序的入口,不过在Main函数执行完后,程序也就终止了。

例如在VB6中我们常常这样写

sub main()

   init()

   frmMain.show

end sub

但是在vb.net中执行完from_load过程,程序就退出了,不是象VB那样继续运行。可以把main函数的代码移到启动窗体的load事件中去,也可以用application.run的方式作为程序的入口点。

firechun(天火)

 

据我分析,Form2的对象实例和其全局变量不是在一起的

这也就是为什么,你Unload,仍然可以引用Form2.i

要想完全切地地销毁Form2

正确的写法:

Unload Form2

Set Form2=Nothing

这样首先卸载Form2对象,然后销毁Form2数据区

 

至于你说的Debug.Print Form2.i 仍然是可以的

不错,那是因为Form2重新被实例化,i是重新分配的内存,数值是空的

会自动Initialize,而不是Load

Load事件应该只有再Load FormForm.Show的时候才触发

 

所以如果你不Set Nothing仅仅是Unload, 那么全局变量是不被销毁的

你仍然可以引用到Form2里的全局变量(数值不会变的)

 

 

说的不对的地方,各位斧正

Rainee(补天)

 

不过看起来两个函数都应该加上by ref才好,效率比较高。

 

--------------------------------------------

这个怎么说,你是说按地址方式引用比较快,是这个意思吧

可是通常考虑到封装的概念,对接口的要求会比较严格

我们规范的写法,在不是特殊情况下都要求使用ByVal

又学到了不少东西:)

 

to nik_Amis(Azrael)

 

关于Byref我有了点感觉了,确实大部分情况下都应该使用传值方式,可以防止函数体内意外的内存操作影响原值,只需要在自定义类或结构(体积比较大)和字符串(个人感觉应该是)两种情况下使用。而且VB.net也把函数参数默认的Byref方式变成了默认Byval了。

 

to firechun(天火)

 

手误,是准备移植到VB.net的,不过昨天尝试了一下,在项目升级后除了一大堆的未声明变量以外,连Mian入口的Modual都被遗失了,估计会有办法解决的,不过暂时不知道从何处下手,只好在VB6中先完成一些规范化的工作。

 

你对Form运作的阐述很精辟,受益匪浅。

 

今天加入了Option Explicit声明,结果一整天都在做定义变量的工作,到现在还没有结束,汗啊……

 

那个Main里面的循环极度简单,就是DoEvent、判断串口(两个)写缓冲的状态并做处理、Loop,至于是否如上面说的会有延迟,等我完成了“规范”的工作之后实际测试一下吧;

 

Sleep是指调用API函数,抱歉没有说明;我的意思是如何处理982K甚至XP的兼容性,各位有什么经验,前车之辙,后车之鉴嘛;

 

绘图控件就是那个PictureBox,不过不是Integer,而是Single;主要用它做一些平面的绘图,如果让我重做,可能我会选择使用OpenGL了,不过我可不是OpenGL高手,就想借个项目学习一下罢了:)

 

to demo001

 

辛好我的鼠标就是双飞燕,呆会儿试试去。

 

听你说起你的项目负责人似乎挺有怨气,其实很多地方都会有这种情况,毕竟安排和管理人是很复杂的事情,先做好你手头的工作,有空多学习,早晚有一天你会有机会施展拳脚的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值