Flex SDK 编码标准与最佳实践:
遵循一定编码规范能够使源码看起来前后一致、组织良好、更加专业。
本部分内容包括:1. 命名;2. 语言使用 3. 文件组织 4. 格式 5. ASDoc
1. 命名
缩写:能避免就避免,代码清晰永远比减少打字重要;但是也要记住一些标准化了的通用的缩写,比如acc(accessiblility) , auto(automatic), impl(implementation), info(infomation), num(number), min(minimum), max(maximum), nav(navigation), regexp(regular expression), util(utility)等等。使用缩写时尽量和Flex保持一致;
首字母缩写词:要么全部大写要么全部小写。当首字母缩写词当成一个标志符或者标志符的开始部分,且这个标志符必须以小写字母开始的时候才采用全部小写的方式。
词语边界:标志符多个单词构成的时候,单词首字母大写,或者词语以下划线隔开,比如LayoutManager, object_proxy;当多个首字母缩写词邻接的时候遵循首字母缩写词规范,但是尽量避免。
指定类型的名字:如果你要将某一个类型组合到一个名字中去,那么把在加在最后,比如命名命名一个border图形可以使用:border, borderSkin, borderShape;最好的名字就是类型的小写比如:Button的实例button。
包命名:使用小写字母,之间大写字母隔开,比如controls, listClasses;包名称最好是名词或者动名词,不要用动词、介词、形容词、副词之类。当一个包的作用是实现某一功能的时候最好使用动名词,比如bingding, logging, messaging, printing;支持组件FooBar的最好写作fooBarClasses;
文件名称:对于重要的API文件,文件名称必须和重要的公开API保持一致,但是include文件不一定要遵循此规则;对于包含文件比如用作Styles的,大写字母开始,各个单词隔开,且在最后加上Styles: BorderStyles.as, ModalTrasparencyStyles.as; 对于资源文件小写字母开始,下划线隔开:icon_align_left.png;
命名空间名称:小写字母、下划线隔开:mx_internal, object_proxy
接口名称:字母“I”开始、大写字母间隔:IList, IFocusManager, IUID
类名称:大写字母开始、大写字母间隔:Button, FocusManager;Event子类(FoobarEvent),Error子类(FooBarError),皮肤类(FooBarBackground, FooBarBorder, FooBarIcon...),utility类(FooBarUtil,不是FooBarUtils,包是复数,类是单数);
事件名称:小写字母开始、大写字母间隔:move, creationComplete
Style名称:小写字母开始,大写字母间隔:color, fontSize;
字符属性枚举值:auto, filesOnly;
常量命名:全部大写字母,下划线间隔:OFF, DEFAULT_WIDTH,如果常量是一个字符串,那么常量命名和常量值保持一致: ;
属性名命名:小写字母开始,大写字母间隔: i, width, numChildren;
使用i作为选还变量,n作为循环上界;使用j作为循环变量,m作为循环上界:
for (var i:int = 0; i < n; i++)
{
for (var j:int = 0; j < m; j++)
{
...
}
}
使用p作为loop循环的变量:
for (var p:String in o)
{
...
}
如果子类的getter/setter覆盖了基类的getter/setter,但是同时又想继续公开基类的getter/setter,那么这个时候应将基类的属性名前加上“$”作为子类属性名,并且子类的属性名应该标志为final,且除了调用基类getter/setter外不应该做其它的事情:
mx_internal final function get $numChildren():int
{
return super.numChildren;
}
存储变量命名:getter/setter属性foo所存储的变量应该是_foo(加上下划线);
方法命名:小写字母开始,每个单词大写字母间隔,应该使用动词:measure(), updateDisplayList();无参方法应该实现为getter/setter,而不应该是getFooBar(), setFooBar();当然,如果getFooBar()是一个需要大量计算的慢速度方法的话就应该命名为findFooBar(), calculateFooBar(), determineFooBar()等等,而不是getter;如果子类的某方法覆盖了基类的某方法,但是同时又想继续公开基类的某方法,那么这个时候应将基类的方法名前加上“$”作为子类方法名,并且子类的方法名应该标志为final,且除了调用基类方法外不应该做其它的事情:
mx_internal final function $addChild(child:DisplayObject):DisplayObject
{
return super.addChild(child);
}
事件处理器命名:在后面加上Handler:mouseDownHandler();如果事件处理器是用来处理组件的某一个子组件的事件的话,那么就应该把子组件的名称加到最前面,并且用下划线隔开:textinput_focusInHandler() (textinput的focusin事件的handler);
参数命名:setter值使用value:public function set label(value:String):void; 事件参数使用event:protected function mouseDownHandler(event:Event):void;
资源包名称:为某一包服务的资源包名称应该和包的名称保持一致;
资源键名称:小写字母,每个单词大写字母隔开;
杂七杂八:避免使用“object”,因为它不明确;“item”是数据项,不是显示对象;renderer是显示数据项的显示对象;“type”是AS3类型,否则使用“kind”;
2. 语言使用
这个部分讨论AS3的语言构造,尤其当某一事情有多种表示方法的时候;
编译选项:编译的时候要使用-strict –show-actionscript-warnings(flex-config.xml默认);
基于属性的API:应该偏向基于属性的API而不是基于方法的API,因为这对于声明示的MXML来说更加有利;
类型声明:尽量为每个变量、参数、返回值等编写注释;参数类型尽量准确,比如循环变量应该是int,而不是Number,更不是Object;鼠标事件处理器的参数应该是MouseEvent而不是Event;如果值可以是undefined的话那么使用“*”,这种情况下可以使用Object代替,null表示undefined;如果声明变量为Array,则应该使用“/* */”马上注明数组的成员类型:var a:Array /* of String */ = [];
function f(a:Array /* of Number */):Array /* of Object */
{
...
}
保留字:
undefined尽量避免使用;
int和uint:整数后面不要加小数点,十六进制用0x开始,后面的字母大写;
RGB色通常用六个十六进制数字表示;
索引值-1表示“没有索引项”;
Number:通常表示可以带小数,所以即使变量是整数也应该加上一个小数点和一个零,比如alphaFrom = 0.0; alphaTo = 1.0;但是屏幕坐标值不要这样做;
指数计数的时候使用e,比如1.0e12,不要用大写E;
String:使用双引号界定字符,即使字符中间包含引号:字符what’up, “Big Boy”?表示为"What's up, \"Big Boy\"?", 而不是’what\’s up “Big Boy”?’;
Array:使用“[]”, 而不是new Array(),比如[1, 2, 3]而不是new Array(1, 2, 3);这里在一个数组变量的时候容易出问题,比如一个包含一个值3的数组,如果用new Array(3),那么表示的是建立了一个三个元素的数组[undefined, undefined, undefined], 而不是[3];
Object:使用{}, 而不是new Object();比如{}, {a: 1, b: 2, c: 3};
Function:避免使用匿名函数,用类方法或者包方法代替;如果一定要用,那么声明返回值,并且函数体内最后一个语句用分号结尾:function(i:int):void { doIt(i - 1); doIt(i + 1); }
RegExp:不要使用正则表达式构造函数创建正则表达式,使用var pattern:RegExp = /\d+/g; 而不是var pattern:RegExp = new RegExp("\\d+", "g");
XML和XMLList:直接使用保留字声明,不要使用构造函数。使用var node:XML = ;而不是var node:XML = new XML(""); XML属性值要使用双引号括起来,不要使用单引号。
Class:只有当需要在区分两个导入类的时候才使用类的全名,
正确做法(Yes:):
import mx.controls.Button;
...
var b:Button = new Button();
错误做法(No:):
import mx.controls.Button;
...
var b:Button = new mx.controls.Button();
正确做法:
import mx.controls.Button;
import my.controls.Button;
...
var b:Button = new mx.controls.Button();
表达式相关:对于通用的操作符(+, -, *, /, &&, ||, , >=, ==, !=)不要使用不必要的圆括号;其它的优先级不容易记住的可以借助圆括号。
强制类型转换:不要将Boolean变量和true或false比较;显式的将int,uint, Number, String转换为Boolean值,使用if(n !=0 ) 而不是if (n), 使用if (s != null && s != “”)而不是if (s),对于对象引用来说可以隐式转换为Boolean值,使用 if (child) 而不是if (child != null),使用if (!child) 而不是if (child != null);使用强制类型转换而不是as操作符,仅仅当强制转换可能失败并且你希望失败的时候值为null而不是抛出异常。使用IUIComponent(child).document而不是(child as UIComponnet).document;
比较:以更容易理解的方式书写比较表达式: if (n == 3) // "if n is 3"(Yes), if (3 == n) // "if 3 is n"(No);
++ 和 –操作:前缀形式和后缀形式效果一样的时候使用后缀形式,只有当你想在变量在操作之前使用的时候才使用前缀形式;
三元操作符:可以使用三元操作符代替简单的if/else 逻辑,尤其是对null进行判断的时候;
return item ? item.label : null (Yes)
if (! Item)
return null;
return item.label; (No)
但是不要使用嵌套的三元操作符;
new:即使构造的类不带参数也要使用圆括号:var b:Button = new Button(); (yes) var b:Button = new Button;(No);
声明:每一个声明语句都使用分号结尾。
include:使用include 而不是已废弃的#include,和前面一样,每个声明语句以分号结束;使用相对路径而不是绝对路径;
import:导入明确的类,避免使用通配符“*”;
use namespace :避免使用,非公开名字空间引用使用“::”:
Yes:
import mx.core.mx_internal;
// Later, in some method...
mx_internal::doSomething();
No:
import mx.core.mx_internal;
use namespace mx_internal;
// Later, in some method...
doSomething();
if:当if/else 分支只有一句声明的时候,不要用{}括起来;
Yes:
if (flag)
doThing1();
――――――――――――――――――――――――――――――――――――
if (flag)
doThing1();
else
doThing2():
―――――――――――――――――――――――――――――――――――――
No:
if (flag)
{
doThing1();
}
―――――――――――――――――――――――――――――――――――――
if (flag)
{
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/12639172/viewspace-331072/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/12639172/viewspace-331072/