5/11/2008

读林斌博士写好代码十个秘诀

软件的质量属性
鲁棒 - Solid and Robust Code
简洁 - Maintainable and Simple Code
高效 - Fast Code
简短 - Small Code
共享 - Re-usable Code
可测试 - Testable Code
可移植 - Portable Code
集百家之长, 归我所用 - Follow Basic Coding Style
1.代码能够清晰的表达你的思路
2.代码应该具备自解释能力,注释代码别是单纯解释语句,这种注释毫无意义
3.编码的缩进和排版规范
4.所有的函数和变量应有他人容易理解的名字
5.将Tab键改用为4个空格字符
6.减少单个函数的长度,控制在50-100行以内
7.避免幻数,多使用枚举和常量的定义
取个好名字 - Use Naming Conventions
1.采用匈牙利命名法对变量进行命名
2.名字要清晰表达含义,不要怕长
凌波微步, 未必摔跤 - Evil goto’s? Maybe Not…
1.goto的使用应该遵循原则,而不是全盘否定
2.不用写高深晦涩的语句,不要一味追求性能忽视代码可读性
3.模式并不是一味正确,特定问题更需要考虑反模式
先发制人, 后发制于人- Practice Defensive Coding
1.尽量保持代码的简洁和简单
2.调用其它接口和函数时候首先对返回值进行检查
3.避免有符号/无符号,32位/16位,被零除等误算情况
见招拆招, 滴水不漏 - Handle The Error Cases: They Will Occur!
1.通过异常处理机制来保证程序代码的健壮性
2.异常处理中一定要注意资源的释放
3.异常处理要关注日志的详细记录,便于后续BUG分析
4.不用把后台编码或系统异常直接抛给用户
熟习剑法刀术, 所向无敌 - Learn Win32 API Seriously
1.Win32 API是微软平台编程根本
2.对系统强大的公用类库的熟悉和整理将事半功倍
双手互搏, 无坚不摧 - Test, but don’t stop there
1.如果你没有进行测试,你完成的代码将仅仅是个半成品
2.尽可能多的对自己的代码进行测试
3.编码人员应该更专注于白盒测试和单元测试
4.要善于使用JUnit,NUnit,PureCoverage,Compuware,NCover等测试工具
5.相互间的Review和走查是对代码可维护性的重要测试手段
6.有特殊性能要求时候需要对相关功能或模块单独进行性能测试
活用断言 - Use, don’t abuse, assertions
1.断言可以很好的描述假设和不可能的情况
2.断言对程序Debug很有用,可以尽早的发现程序问题
草木皆兵, 不可大意 - Avoid Assumptions
1.考虑到用户使用的各种场景
2.不用假设用户会正确输入数据,要做好各种完整性和边界的检验
3.程序中70%左右代码是为了保证这种完整性服务的,正常条件下功能可能30%代码就实现了
最高境界, 无招胜有招 - Stop writing so much code
1.一味拷贝粘贴代码就是在制造拷贝BUG,这种代码对系统无任何意义
2.编码过程注意重用,函数级->组件级->系统级
3.通过重构持续改进代码质量,改进自我逻辑思维
最后总结下:
1.养成良好编码习惯,你面试的一小段代码可能就足以展现你全部陋习。
2.熟练使用好各种辅助工具,但不要全部依赖工具,最主要是学习分析和设计的思考方式
3.注重单元测试,关注程序性能,可维护性,可测试性是编码技能提升重要手段
4.通过重构使编码过程形成完整闭环的反馈回路,重构能力可以很好体现自己的设计能力
5.养成良好习惯,形成自己的编码过程检查单,多请教老员工可能事半功倍。

5/10/2008

Eclipse Process Framework: a new tool for porject process management

Eclipse Process Framework (EPF)提供了一个可订制的软件过程控制框架,这个框架集成了一些典型的过程控制的理念和工具,以此来支持各类工程和开发风格。

项目目标:

1. 为过程控制提供一个可扩展的框架和一些代表性工具。如方法和过程的分配,库管理,配置和发布一个过程
2. 提供典型的并且可扩展的过程概念,他们能为各种软件的开发和管理过程提供迭代的、灵活的和递增的开发,并且能应用于更广泛的开发平台和应用。

Some advices for API designing

设计需要进化
API的价值就在于能够帮助你完成许多功能,但请不要忘记要持续的改善它,否则它的价值就会逐渐减少。而且要根据用户的反馈信息,来改善API,或者说是 对API进行演化,另外改进API时要注意的就是在不同版本间要保持兼容性,这点至关重要,它也是一个API是否成功的重要标识之一。 如果一个功能以API的方式公布出来,那么在发布以后,它的对外接口就已经固定,无论什么情况,都不能取消,而且一定要能够按照原有的约定功能正确执行。 如果API不能在版本间保持兼容性(译注:这里应该指的是向下兼容),用户将会难以接受这样一个千变万化的API,最终的结果只能是让用户放弃使用你的 API。如果你的API被大量的软件或者模块所使用,又或者被大型软件使用,这个兼容问题也就愈加严重。
通常情况下,你不知道用户如何使用API来完成工作。除非能够确认API的修改对用户的代码不会造成破坏,才可以考虑修改API。,反之如果API的改变 会影响用户现在的代码,就必须有一个足够的理由。只有意识到对API的修改,会严重的破坏用户现有的代码,在修改API时才会谨慎地,尽量地保证API兼 容性。修改API的时候要尽量避免以下几种情况,以免对用户的代码产生破坏:
降低方法的可见性,如将public变成proteced,又或者将protected变成private。
修改方法的参数,如删除一个参数、添加一个参数、或者是改变参数的类型,尤以后两者更为严重。
当API的设计和开发到了一定阶段以后,可能会发现以前的版本已经出现了一些问题,又或者需要添加新的功能,此时设计人员完全可以重新创建新的API,并 放到新的包中,这样就可以保证那些使用老版本的用户可以很轻松的移植到新版本上,而不会产生问题。请牢记一点:添加新的功能,请不要修改原有的内容。


API的设计目标

设计一个API要达到哪位目标呢?除了兼容性以外,也从Elliotte的讨论中提出一些目标。
API的正确性必须保证:
无论用户如何调用API,都不应该产生错误。

API的易用性:
API必须易于使用。通常易用性一向难以评价。但是有一个办法可以有效的提高易用性,就是编写大量范例代码,并将其很好的组织在一起,从而为用户提供API参考。(译注:个人认为一个好的FAQ可以提供各种API使用的范例。)
API必须易学:
很大程度上,API的易学和易用性是相似的,一般来说,易用也就易学。如果要使API易学,下列基本原则要遵循的:
API越小就容易学习;
文档应该有范例;
如果方便的话,尽可能将API与一些常用的API保持一致。例如如果要做一个资源访问的API,尽可能与J2SE中的IO使用一致,自然很容易学习。
(译注:如果你要关闭一个资源,就象Java的File,Connection一样,使用close,而不是destroy。)

API的运行速度必须够快:
Elliotte也是考虑了很久,才给出这一条。但是要在保证API简单而且正确的前提下,再来考虑API的性能问题。

API必须足够的小:
这里所说的小不仅是指编译后代码的文件比较小,而且更重要的是运行时占用的内存要小。之所以提出最小化的概念,还有一个原因:就是因为很容易为API添加 新的内容,但是要将一个内容从API中移出就很困难,所以不要随便向API中添加内容,如果不确定一项内容,就不要将它加入到API中。通过这样一个建议 或者说是限制,可以提醒一个API设计人员更加关注API中最重要的功能,而非一些枝节的问题。

因为考虑的过于详细,功能边界也就越大,所面对的需求也就越多,因此要提供的功能和可供用户调整的功能也就更加庞大,也就是说这种方法会使得API包含很多的功能,最终就是API膨胀性的增长。



如果设计的API过于庞大,必然会包含了许多不必要的方法,至少有许多public的类和方法,对于大部分用户是用不到,也会占用更多的内存,并降低运行效率。这违反了通常的一个设计原则:“不要让用户为他使用不到的功能付出代价”。




下面在设计API时的一些技巧
不变类是一个很好的设计,如果一个类可以设计成不变类,就不要用可变类!如果详细了解这样设计的原因,请参见《Effective Java》的第十三条。如果没有读过这本书,很难设计出好的API。

另外字段信息应该是private的,只有static和final修饰的字段信息才能变成public,允许外部访问。这一条是一个非常基础的原则,这里提到这个原则,只是因为在早期的API设计时,有些API违反了这个原则,这里不再给出一个例子了。

避免奇怪的设计。对于代码,已经有了许多约定俗成的方法了,如get/set方法,标准的异常类。即使觉得有了更好的方法,也尽量避免使用这些方 法。如果使用了一些奇怪的方法名称,这样使用API的用户必须学习新的内容,不能按照原有的习惯来理解代码,会增加学习成本,也会增加误用的可能。

一个类如果不是抽象类,就应当是final类不可被继承。《Effective Java》第15章给出了足够的理由,同时也建议每个方法在默认情况下都应该是final(目前Java正好相反)(译注:这点我也赞成,觉得方法默认为 final更好,但是目前Java发展到当前情况下,已经不可能大规模的更改了,不能不说是Java语言的一个遗憾之处,C#这一点处理的更好,默认为 final,后面的留言也提到这个了)。如果一个方法可以被覆盖,一定要在文档中清楚的描述这个方法被覆盖后带来的后果,最好还能提供一些例子程序进行演 示以避免开发人员误用。

总结:
设计需要演化,否则会降低它的价值。
先保证API的正确性,在此基础上再追求简单和高效
接口并不如想像中的那么有用。
谨慎分包可以带来更多的价值。
不要忘记阅读《Effective Java》(译注:难道作者和Josh Bloch's有分赃协议不成。)

5/09/2008

Tunapie - Linux下的网络电台

Tunapie,一个可以自动从网络上下载网络电台和视频流媒体的列表软件。在Windows下用过WinAMP的用户应该都有印象WinAMP有一个可 以从网络更新列表,用户可以选择电台或视频流媒体。Tunapie就是WinAMP这个功能的独立软件,当然是For Linux的。
要播放 Tunapie提供的列表里的网络电台或视频流媒体,你需要保证系统里安装有XMMS音频播放器和totem/xine/mplayer任意一个视频播放 器,这样子才可以播放Tunapie提供的列表里的资源。当然,如果你有其它类似的软件同样播放能力,你可以在Tunapie的Preferences里 选择设置播放器。
官网:
http://tunapie.sourceforge.net/

How To Design a (module) API

A description of good design practices when design any APIs with especially closer look to the case of an API based on NetBeans infrastructure is content of this evolving document.

What is a API?
As the reason why API is used is to allow communictation between teams and applications in order to allow separated and distributed development the answer to question what is API shall include everything that influences such kind of development.

The API is everything that another team or application can depend on:

  • method and field signatures - communication between applications is usally about calling functions and passing data structures between each other. If there is a change in the names of the methods, in their arguments or in structure of exchanged data, the whole program often does not even link well, nor it can run.

  • files and their content - many applications read various files and their content can influence their behaviour. Imagine application relying on the other one to read its configuration file and modifying its content prior to invoking the application. If the format of the file changes or the file is completely ignored, the communication between those applications gets broken.

  • environment variables - for example behaviour of cvs can be influenced by the variable CVSEDITOR.

  • protocols - opening a socket and being prepared to interpret streams sent there, or putting or reading a data to clipboard or during drag and drop again establishes an API that others can depend on.

  • behaviour - a bit harder to grip, but important for the separation as well is the the dynamic behaviour. How the program flow looks like - what is the order of execution, what locks are being held during calls, in which threads a call can happen, etc.

  • L10N messages - because the localization to a certain language is usually developed and distributed by somebody other than the person that writes the code, yet both of them have to use the same keys (NbBundle.getMessage ("CTL_SomeKey")), there is inherently a contract between the writer of the code and the translator - an API of sorts.
The important thing with respect to distributed development is to be aware of possible APIs - of possible things other code can depend on. Only by identifying such aspects of own application one can develop it in a way that will not hurt cooperation with seperately developed applications.

web resource:
google video:http://video.google.com/videoplay?docid=-3733345136856180693
book in amzoe The Definitive Guide to API Design (The Definitive Guide) (Hardcover)

5/08/2008

User-centered Design in web page

GUI were designed to give people control over there computers. Users now exect a level of design sophistication from all graphic interfaces, including web pages. The goal is to provide for the needs of all your potential users, adapting web technology to their expectations and never requiring readers to conform to an interface that places unnecessary obstacles in their paths.

电子商务网站的界面规划建议

相比国内的电子商务网站,国外的网站看似效果简单,实则内涵丰富,简约而不简单,是深入研究过用户心理学的产物。电子商务网站的界面规划,有几个地方要注意:
1、 产品类别规划不但要精确,更要易懂。
类别划分要符合用户的阅读习惯,类别不是划分得越细越好,相反,同时展示给用户的大类不要超过10类,类别索引要循序渐进,不要让用户在查找类别上耗费太多时间。
2、 页面的视觉流程要清晰
1) 版块布局要大小适宜,重点突出。电子商务网站的版面规划需要做到——大小适宜,重点突出。要根据网站的重点,对于内容进行合理的版块规划,页面需要有视觉焦点,各版块大小分配轻重要合理,不能将版块都均衡分配。
2)色彩搭配要协调,主次分明。网站需要有主色与辅助色,一个网站页面上同时出现的色彩不宜超过三种,色彩主次要分明。电子商务网站应该以产品展示为主,网站色彩的运用不能喧宾夺主。
3)字体及图标的应用要节奏和谐,适合阅读。为了吸引用户在网站上停留得久些,电子商务网站不仅要有精美的产品图片,更要有适合阅读的字体。虽然网页上一般是采用默认的宋体,但是在文字的大小、间距、粗细、颜色上依然要有所考究。文字就像有节奏的音符,恰当的文字排列使得用户阅读更加舒适,不当的文字排列则降低用户的阅读兴致。节奏和谐的文字排列将增强用户的阅读时间。
3、 flash的应用要慎重。
恰当的FLASH应用能为网站锦上添花但是网站上尽量不要多个FLASH同时出现,如果有,也要设定为可关闭。要让用户在无干扰的情况下浏览网站,而不能让FLASH将用户赶跑。

5/06/2008

the problem of vmvare under the ubuntu 8.x is resloved

The vmware was not available sice i updated my system from 7.x to 8.x. this is a bad thing for me.but i have find a method that can resolve this problem today, the process is the following .you should use the update package
step 1) down load the package named vmware-any-any-update-116.tgz. then extract the patch to desktop
step 2 ) cd Desktop/vmware-server-distrib step
3 ) ./vmware-install.pl Keep all the defaults and do everything until it asks if you want to compile the kernel then say no ( if you say yes it is not that big of a deal it will just fail ) step 4) cd ../vmware-any-any-update116/
step 5 ) ./runme.pl make sure to say yes to compile kernel and follow defaults

5/03/2008

MySQL的日期和时间类型+PHP中的日期和时间函数

1. MySQL的日期时间列类型:
a. YEAR[(2|4)]

取值范围:2位为70-69 表示1970-2069; 4位表示1901-2155;
b. DATE
范围:1000-01-019999-12-31 格式为YYYY-MM-DD
c. TIME
范围:-838:59:59838:59:59,格式为HH:MM:SS,注意其范围比想象的宽的多
d. DATETIME
范围:1000-01-01 00:00:009999-12-31 23:59:59,表示日期和时间,格式为

YYYY-MM-DD HH:MM:SS
e. TIMESTAMP[(M)]
范围:1970-01-01 00:00:002037年,表示格式有多种决定与M值:
TIMESTAMP: YYYYMMDDHHMMSS (14
位默认)
TIMESTAMP(14): YYYYMMDDHHMMSS
TIMESTAMP(12): YYMMDDHHMMSS
TIMESTAMP(10): YYMMDDHHMM
TIMESTAMP(8): YYYYMMDD
TIMESTAMP(6): YYMMDD
TIMESTAMP(4): YYMM
TIMESTAMP(2): YY

使用这些类型:

如果仅保存年使用YEAR
保存日期使用DATE
保存时间使用TIME
保存日期和时间使用DATETIME或者TIMESTAMP
另外注意取值范围

2. PHP中的日期和时间函数
1
Unix timestamp
Unix timestamp
表示把日期和时间转换为秒表示(距离Jan 01 1970时间差

参考http://www.unixtimestamp.com/
尽管这种方法计算时间比较方便,但是面临最大值问题即若达到January 19, 2038将会出现32位溢出。
2
PHP中常用的日期和时间函数:
尤其注意这里的timestampUnix timestamp即为距离1970-01-01的秒数。
和之前介绍的MySQL中的TIMESTAMP类型不同

(TIMESTAMP类型都是YYYYMMDDHHMMSS的格式,而不是秒数)
a. date(format,timestamp):
能够获取当前时间或者将已有的timestamp,转化为各种格式,通过format字符串可以定义格式。参考http://www.w3schools.com/php/func_date_date.asp
b। getdate(timestamp):
能够获取当前时间或者将已有的timestamp,转化为一个array
参考http://www.w3schools.com/php/func_date_getdate.asp
c। mktime(hour,minute,second,month,day,year,is_dst):
获取现在时间或者将已有的时间转换为timestamp
http://www.w3schools.com/php/func_date_mktime.asp
d. time()
获取当前时间的timestamp形式
http://www.w3schools.com/php/func_date_time.asp

3. 小结:
1

使用日期和时间,MySQL中的类型可以用DATETIME或者TIMESTAMP
两者分别保存为YYYY-MM-DD HH:MM:SSYYYYMMDDHHMMSS
PHP方面可以使用date(format, timestamp)函数配合使用,因为date函数能够设置format将日期转化为符合DATETIME或者TIMESTAMP的格式保存起来。

2
)另一方面,在PHP中要习惯使用Unix timestamp这种形式的日期和时间,因为很方便计算,而且有很多函数方便使用。如果直接保存Unix timestamp可以将MySQL中的列类型定义为int(12)类似的整型就可以。

从PHP 5.1开始,date/time函数有一些变化,其中一项就是时区的设置。php.ini里增加了对应的设置date.timezone,同时也增加了相 应的函数date_default_timezone_get()和date-default_timezone_set()。如果不设置且未在程序中指 定,可能会在使用date/time函数时产生时差问题(win32平台就是)。
date_default_timezone_get()对时区的判定按照以下顺序:
  • 使用date_default_timezone_set() 函数所设置的值(如果有)

  • TZ 环境变量(如果非空)

  • php.ini中的date.timezone 选项(如果设置过)

  • "magical" 推测(如果操作系统支持)

  • 如果以上选项没有一个成功,则返回UTC

php.ini的选项如下:
[Date]
; Defines the default timezone used by the date functions
date.timezone = Asia/Shanghai
中国可以定义为Asia/Shanghai
或者使用date_default_timezone_set()函数
bool date_default_timezone_set ( string timezone_identifier )
timezone_identifier可以参看PHP文档的Appendix H, List of Supported Timezones。php.ini中的设置也使用这些值。