目前位置: VCer资源中心 >>> VCer文章 >>> 软件工程

[本帖已阅读3034次 分值90 回复0次] 张贴资源 发回信箱 控制面板

白乔原创:艺术编程之C++篇[4]

提供者:bluejoe 张贴时间:2004-04-10 12:22:34.0 出处:vcer.net 作者:不祥

白乔原创:艺术编程之C++篇[4](2004-04-10 12:22:34.0)


白乔


 
级别: VCer师长
头衔: VCer创始人

经验: 21093
作品: 513
分会: 华北分会
注册: 2003-12-01 09:20:32.0
登录: 2008-11-17 19:35:24.0

3 编写有用的代码——代码的可用性

中国的程序员都不大喜欢公开代码,自己写的程序模块别人很难也很少有机会用得上,这是一件很奇怪的事情。每个自诩为很“牛气”的程序员总在花费相同的时间做着和别人重复的事情。很少人在自己拷贝来的代码中声明别人的版权,这确实是太奇怪了。

这样的事情发生,一方面与思维习惯有关,对国人来说,程序是用来使自己出名的,而不是使别人出名的,程序的源码和资料别人当然别想拿得到;另一方面,这样的情况与国人程序的质量有关,别人的程序拿过来,用不了,或者用得很不舒服,还不如自己重新写一个,其结果,当然会造成闭门造车,“百家争鸣”——而这绝对不是好事。

本章节引导你如何不浪费时间(自己的,和别人的)重复劳动。

3.1 别的系统可以用吗?——可移植性(portability)

你做的程序在别的平台也可以用吗?“应该没问题”,这是大多数程序员的回答。之所以“应该”,是因为程序员心里没底,在程序开发过程中程序的移植性一直是个门外话题。这样的程序拿出来,正如将中国的演员明星拿到好莱坞,让人心里总是没底。

以下是一些提高程序的可移植性的建议:

  • 将“设备相关程序”与“设备无关程序”分开。正如Java的虚拟机与.class字节码文件其实就是将一个完整的程序分成两部分;
  • 将“功能模块”与“界面模块”分开。如果开发一个网络服务端,你的程序很有可能不在Windows里运行,而有可能运行于其他系统,如Solaris;
  • 使用系统提供的可移植性好的API,不要另起炉灶。笔者曾经开发了一个Flash动画浏览器,其中的目录浏览模块在最初的版本里,“桌面”的位置是通过某个可移植性不是很好的函数得到的,结果程序在Windows Me里就大丢洋相。后来笔者参考了CJLib,采用了SH级函数,从而得到了与“资源管理器”完全类似的浏览界面,实践表明,该程序在Windows 95的后续版本运行一切正常;

编程语言越低级,其程序越难移植,反之更容易。例如C程序比汇编程序的可移植性好,Java的平台无关性比C/C++好。

追求可移植性可能永无尽头,你最好悠着点,差不多就够了,不要老奔下去。

3.2 别的应用程序可以用吗?——可扩展性(expansibility)

这里的“可扩展性”指程序的可二次开发性和其他模块的可用性。不要假设你程序的用户就只有最终用户,其他的应用程序,别人写的,或者你写的,都有可能用到现在的程序。你准备好了吗?

为了更好地实现程序的可扩展性,以下是一些推荐的建议:

  • 尽量将程序分块,不要集大成。仅仅就一个exe文件提供给用户,恐怕他唯一能做的是运行这个程序。将程序分块,尽可能地提供有益的lib、dll或者ocx,或者更底层的驱动程序,可以让别人有更多的机会共享你的蛋糕;
  • 尽量采用标准存储格式。在合适的地方采用标准的存储格式,如xml或者数据库文件,或者注册表,这样其他的程序员就可以通过存储介质了解到你的程序。注意要合适,不要将用户的密码文件存储为明文TXT。Internet Explorer是个好例子,它的一些行为参数(例如:主页地址、是否全屏显示、用户访问过的站点等等)就保存在注册表里,如图9所示:

图9 Internet Explorer在注册表保存参数

一旦用户程序修改了这些配置, Internet Explorer的下一次运行就会反映出这些变化。

  • 准备接收入口参数并返回出口参数。Internet Explorer仍然是个好例子,你可以指定它打开某个站点,并隐藏菜单和工具栏。让你的程序接收命令行参数,并在程序结束时返回有意义的代码。例如:假设你正在开发一个手机短信的发送程序,就应该考虑让它支持如下的外部调用:

当信息发送成功时,sendmsg.exe就该返回0;否则返回相应含义的错误码。

  • 采用消息机制。接收从其他程序发送来的Windows标准消息和程序自定义的内部消息;
  • 提供头文件和详尽的开发资料。这是最重要的,否则其他的程序员将无从下手。Flash控件是共享控件,可是在笔者开发Flash动画浏览器的时候,没有任何相关的资料,结果笔者只好借助Visual C++自动导出的的头文件慢慢摸索,其艰辛可想而知(当然,这不是提供商MacroMedia的错);
  • 提供demo程序(演示程序)。演示程序的正确用法;不仅仅游戏程序需要demo版本,你的程序,也应当提供合适的demo;
  • 提供About窗口。在合适的地方显示版权信息和你的联系方式,如下为CJLib SDK中无处不在的版权标识图案:

图10 CJLib的版权标识图案

3.3 别的程序员可以用吗?——复用性(reusability)

现在轮到你公开源代码的时候了,公开源代码,受益者不仅仅是得到代码的人,也包括你。永远没有完美的程序,你的代码也许就隐含着某个致命的错误,你在程序开发中可能有各种不好的编程习惯,而别人会帮你指出来。

要学会为别人写程序,很多偷懒的学弟拿到师兄的程序,先是一阵狂喜,接着是叫苦连天,个中悲喜滋味一言难尽。这种悲剧的发生,其原因就在于,那个拿到毕业证书蒙骗过关的师兄并没有学会为别人写程序。

增强程序的复用性,以下是一些建议:

  • 编码符合艺术规范。何为“艺术规范”?参见1.1节;
  • 提供头文件和详尽的开发资料。在头文件提供大部头的注释和版权声明;
  • 提供demo程序。引导其他的程序员从何开始,功能尽可能完全、系统,有利于别人快速了解你的源码;
  • 良好的封装性。良好的框架应该设计成模块化的、黑箱式的。如果你提供给别人的是一个封装性完好的类,开发者不需要再考虑其中的繁文缛节,不需要自己再去管理你的类成员,他所需要做的仅仅是使用你的类去创建实例对象,或者干脆去再派生一个,那么这样的源码应该是很受欢迎的;
  • 采用消息机制,尽可能提供虚函数。虚函数即基类为派生类提供的接口,接口越多,程序员对源代码的控制就越大。MFC框架类之所以应用颇广,支持消息映射和提供虚函数接口是主要原因,例如CWnd类就提供了129个消息映射函数和31个虚函数。

一个封装性良好的类是最受程序员欢迎的,类的各种优点在此不再展开,以下是开发者在设计可复用类应遵循的参考原则:

  • 提供类的递归介绍,提供继承层次图(Hierarchy Chart)。层次图有助于程序员直观地了解类在整个框架里的位置和角色。Visual C++的MSDN是个很好的例子,如图11即为CView的继承层次图:

图11 CView的继承层次图

很多Visual C++程序员都是从这个CView开始Windows编程的。

  • 减少参数的数目。具有六个以上的参数的函数就很难让人看明白,如果参数确实很多,建议使用对象参数。这样做,同样也会大大降低产生问题的可能性。
  • 减小函数的体积。你的函数不要太长,50行以上的代码就会显得复杂难读,如果代码确实很长,尽量按功能划分成更小的模块。
  • 顶层的类设计成抽象类(abstract class)。大多数情况下,提供一个抽象基类以支持用户的扩展还是很值得的。程序员可以通过定义抽象基类的功能和行为,让其他程序员快速地了解设计该类的原始意图。
  • 减小对成员变量的访问。尽量不要将类的成员变量暴露给别人(别的类),而是通过函数来保护它们。这样,即使成员变量名发生改变,也只需要修改函数这一个地方。
  • 分割大的类。类的体积大小不一定与它的功能完全成正比,如果一个类具有50多个的函数(呵呵,CWnd除外),最好将它分割成更小的类。
  • 消除“二义性错误”的可能性。函数重载与函数覆盖是C++中很有用的特性,但使用不当会造成错误。有时候,程序员定义的函数接口本身并没有错,但很容易造成用户的调用错误,以下即为“二义性错误”:

一调用foo(1),编译器就会无所适从,程序员有必要避免这类错误的产生。

以上介绍如何设计良好的类以实现代码的复用。此外,程序的质量是影响代码复用的重要因素。不要死循环,不要内存泄漏,也不要一声不吭就死机。

注:转载文章需注明来源:VCer.net 文章地址:http://vcer.net/1288.html

  如果你觉得VCer.net不错,而且你愿意为VCer.net捐赠一元钱,那么点击后面的捐赠按钮吧:) vcer.net捐赠

1082687209616[385,308字节]

得意,我用他的代码;

自豪,他用我的代码!

[回复该贴] [加入个人书签]
[连载系列]

[1] 白乔原创:艺术编程之C++篇
[2] 白乔原创:艺术编程之C++篇[2]
[3] 白乔原创:艺术编程之C++篇[3]
[4] 白乔原创:艺术编程之C++篇[4]
[5] 白乔原创:艺术编程之C++篇[5]

[投票结果]

A: 评分 10 100% (1 票)
B: 评分 5 0% (0 票)
C: 评分 0 0% (0 票)
D: 评分 -5 0% (0 票)
E: 评分 -10 0% (0 票)