Flex SDKコード記述に関する規則とベストプラクティス
メモ: 本ページのコンテンツは執筆が完了しているわけではありません。一部、「後日発表予定」と記された部分が含まれていますが、今すぐ役に立つ情報も豊富に掲載されています。
はじめに
本文書では、ActionScript 3でオープンソースFlexフレームワークコンポーネントを記述する際のコーディング規則を示します。 以下の規則に従うことで、ソースコードの体裁の一貫性、整頓性および専門性を確保することができます。
コードを記述するにあたり常に汎用的な「最善策」があるとは限りません。したがって、以下に示す規則の中には無作為に決定されたものも含まれますが、 一貫性を確保するためにも、Flex SDKプロジェクトの有志に対して以下の規則を遵守することを要望します。
コンテンツ
- 命名規則
- 言語使用法
- ファイル構成
- 記述書式
- ASDoc
命名規則
扱いやすく、そして、わかりやすいコードを記述するには、適切な名前を付けることが不可欠です。 特にパブリックAPIとなるようなケースでは、名前が適切であるかについて、時間をかけて検討するように心がけてください。
我々がここで採用する命名規則は、ECMAScriptおよびFlash Player 9のそれと大部分において整合性があります。
略語
原則として略語の使用を避けるようにします。 たとえば、{{calculateOptimalValue()}}というメソッド名の方が、{{calcOptVal()}}より適切です。
ここでは、キーをタイプする量を減らすことより、内容を明確に示せることの方が重要です。 また、略語を避けることで、「qualified」という単語の略が「qual」「qlfd」のどちらであったかなど、後で頭を悩ませることを回避することができます。
ただし、一部の略語に関しては以下の通りに標準化しています。
- acc: accessibility(アクセシビリティ)。使用例: ButtonAccImpl
- auto: automatic(自動)。使用例: autoLayout
- auto: automatic(自動)。使用例: autoLayout
- eval: evaluate(評価)。使用例: EvalBindingResponder
- impl: implementation(実装)。使用例: ButtonAccImpl
- info: information(情報)。使用例: GridRowInfo
- num: number(数値)。使用例: numChildren
- min: minimum(最小)。使用例: minWidth
- max: maximum(最大)。使用例: maxHeight
- nav: navigation(ナビゲーション)。使用例: NavBar
- regexp: regular expression(正規表現)。使用例: RegExpValidator
- util: utility(ユーティリティ)。使用例: StringUtil
上記リストには、現在使われているすべての略語が含まれていない可能性があります。 上記に記載のない略語を使用する場合は、あらかじめ既存のソースコードを検証して、すでに同様のものが存在しないかを確認するようにしてください。 存在が確認されなかった略語については、略語使用の適切さについて十分に検討するようにしてください。
なお、一部の略語では(意図的に)その使用・不使用が不整合なケースがあります。 たとえば、大半のケースでは「horizontal」と「vertical」を{{horizontalScrollPolicy}}、{{verticalScrollPolicy}}のように表現していますが、一般的なコンテナ名である{{HBox}}や{{VBox}}に関しては、これらの単語を「H」「V」に略しています。
頭字語
Flex開発を手がける際には、AIR、CSS、HLOC、IME、MX、MXML、RPC、RSL、SWF、UI、UID、URL、WSDL、XMLなど、さまざまな頭字語が登場します。
頭字語の綴りは、必ず大文字または小文字のいずれかで統一します(可: SWF、swf。不可: Swf)。 小文字で統一した表現が適当なのは、頭字語が単独の識別子として使用されるケース、ならびに識別子の最初に頭字語があり、しかも当該識別子の綴りが小文字で始まるべきケースのみです。 なお、識別子の綴りを小文字、大文字のどちらで開始すべきかについては、後述の規則を参照してください。
頭字語を含む識別子としては、CSSStyleDeclaration、IUID、uid、IIME、{{imeMode}}などがあります。
単語の区切り
識別子に複数の単語が含まれる際の単語区切り表現としては、キャメルケース方式(例: LayoutManager、measuredWidth)とアンダースコア(例: object_proxy)の2種類を使用しています。どの種類を使用すべきかについては、後述の規則を参照してください。
一部のケースでは複合語を1単語として扱うかどうかについて不整合な箇所があります。例: dropdown、popUp、pulldown。
ごくまれに頭字語が2つ連続するようなケースも想定されますが、頭字語の綴りに関しては常に規則を守るようにしてください。 実際に使用されてはいませんが、例として{{loadCSSURL()}}のようなケースが想定されます。 このような名前はできるだけ避けるようにします。
型を表す名前
名前の一部として型を含めたい場合は、型を示す単語を名前の末尾に結合します。 ActionScript 1の古い規則であったように、略語の接尾辞(_mc}}など)を連結して型を示す方法は使用しないでください。 たとえば、ボーダーのシェイプであれば{{border_mc}}ではなく、{{border、{{borderSkin}}または{{borderShape}}と命名します。
オブジェクトに最も適した名前は、その型の名前を大文字・小文字の記述だけ変えて表したものであることが大半です。例:
var button:Button = new Button();
パッケージ名
小文字で綴りを開始し、以後の連語はキャメルケース方式で記述します。例: controls、listClasses。
パッケージの名前には、常に、動詞、形容詞または副詞ではなく、名詞または動名詞(動詞に-ingが付いた形)を使用するようにします。
同様のアイテムを複数実装するようなパッケージの場合は、そのアイテムを複数形で示す名前を付けるようにします。例: charts、collections、containers、controls、effects、events、formatters、managers、preloaders、resources、skins、states、styles、utils、{{validators}}など。
特定の概念を実装するパッケージの名前には、動名詞を使用することが一般的です。例: binding、logging、messaging、printing。 以外の場面では、その「概念の名詞」を使用します。例: accessibility、core、graphics、{{rpc}}など。
{{FooBar}}コンポーネントをサポートするクラス群が含まれたパッケージであれば、{{fooBarClasses}}と名付けるようにします。
ファイル名
インポート可能なAPIのファイル名には、必ず、その中に含まれるパブリックAPIと同じ名前を付けます。 ただし、インクルードファイルの場合は、この規則に従う必要はありません。
[Style(...)]}}メタデータ向けのインクルードファイルの名前は、大文字でその綴りを開始し、以後の連語をキャメルケース方式で記述します。そして、最後の単語を「Styles」にします。例: {{BorderStyles.as、{{ModalTransparencyStyles.as}}など。
個別のアセットファイルの名前は小文字でその綴りを開始し、各単語間にアンダースコアを挿入します。例: icon_align_left.png。
>名前空間名
名前の綴りを小文字で開始し、各単語間にアンダースコアを挿入します。例: mx_internal、{{object_proxy}}など。
インタフェース名
名前の綴りを「I」で開始し、以後の連語をキャメルケース方式で記述します。例: IList、IFocusManager、{{IUID}}など。
クラス名
大文字で綴りを開始し、以後の連語をキャメルケース方式で記述します。例: Button、FocusManager、UIComponent。
{{Event}}のサブクラスを{{FooBarEvent}}と名付けます。
{{Error}}のサブクラスを{{FooBarError}}と名付けます。
エフェクトの{{FooBar}}に関連付けられた{{EffectInstance}}サブクラスを{{FooBarInstance}}と名付けます。
{{Formatter}}のサブクラスを{{FooBarFormatter}}と名付けます。
{{Validator}}のサブクラスを{{FooBarValidator}}と名付けます。
スキニングクラスには、FooBarBackground、FooBarBorder、FooBarSkin、FooBarIcon、FooBarIndicator、FooBarSeparator、{{FooBarCursor}}などの名前を付けます。
ユーティリティクラスを{{FooBarUtil}}と名付けます。(パッケージは複数形ですが、クラスが単数形であるため、{{FooBarUtils}}にはなりません。)
ベースとなるクラスには、FooBarBase、ComboBase、DateBase、DataGridBase、{{ListBase}}などを用いるのが一般的です。
イベント名
小文字で綴りを始め、以後の連語はキャメルケース方式で記述します。例: move、creationComplete。
スタイル名
小文字で綴りを開始し、以後の連語をキャメルケース方式で記述します。例: color、fontSize。
ストリングプロパティの列挙型値
小文字で綴りを開始し、以後の連語をキャメルケース方式で記述します。例: auto、filesOnly。
定数名
すべて大文字で綴り、各単語間にアンダースコアを挿入します。例: OFF、DEFAULT_WIDTH。
定数の値がString型の場合は、必ず識別子内の単語を定数の値の単語と一致させます。
public static const FOO_BAR:String = "fooBar";
プロパティ名(変数およびgetter/setter)
小文字で綴りを開始し、以後の連語をキャメルケース方式で記述します。例: i、width、numChildren。
ループのインデックスには{{i}}、上限値には{{n}}をそれぞれ使用します。 内部ループのインデックスには{{j}}、上限値には{{m}}をそれぞれ使用します。
for (var i:int = 0; i < n; i++)
{
for (var j:int = 0; j < m; j++)
{
...
}
}
for-in}}ループの変数には、{{p(プロパティの頭文字)を使用します。例:
for (var p:String in o)
{
...
}
クラスがgetter/setterをオーバーライドし、ベースのgetter/setterを公開し続けたい場合は、ベース名に接頭辞「$」が付いた同名のプロパティを実装することで、これが可能になります。 この場合、getter/setterには{{final}}の印を付け、super getter/setterの呼び出し以外の機能を含めないようにします。
mx_internal final function get $numChildren():int
{
return super.numChildren;
}
ストレージ変数名
getter/setterの{{foo}}のストレージ変数には、{{_foo}}という名前を付けます。
メソッド名
小文字で綴りを開始し、以後の連語をキャメルケース方式で記述します。例: measure()、updateDisplayList()。
メソッド名には必ず動詞を使用するようにします。
一般的に、パラメータのないメソッドには{{getFooBar()}}や{{setFooBar()}}といった名前を付けるのではなく、getter/setterとして実装するようにします。 ただし、getFooBar()}}が大量の演算処理を必要とする「重い」メソッドである場合は、この特徴が明らかになるよう、getterである代わりに、{{findFooBar()、calculateFooBar()、{{determineFooBar()}}といった名前を付けるようにします。
クラスがメソッドをオーバーライドし、ベースメソッドを公開し続けたいような場合は、ベース名の頭に「$」が付いた同名のメソッドを実装することで、これが可能になります。 この場合、当該メソッドには{{final}}の印を付け、superメソッドの呼び出し以外の機能を含めないようにします。
mx_internal final function $addChild(child:DisplayObject):DisplayObject
{
return super.addChild(child);
}
イベントハンドラ名
イベントハンドラには、イベントの種類を示す語句に「Handler」を結合した名前を付けます。例: mouseDownHandler()。
仮にハンドラが、サブコンポーネント(this}}以外のものなど)によってディスパッチされるイベント用のものである場合は、ハンドラ名の前にサブコンポーネント名を付け、これらをアンダースコアで結合します。例: {{textInput_focusInHandler()。
引数名
各setterの引数には、{{value}}を使用します。
正しい記述例:
public function set label(value:String):void
誤った記述例:
public function set label(lab:String):void
誤った記述例:
public function set label(labelValue:String):void
誤った記述例:
public function set label(val:String):void
各イベントハンドラの引数には、(e、{{evt}}および{{eventObj}}ではなく){{event}}を使用します。
protected function mouseDownHandler(event:Event):void
リソースバンドル名
リソースバンドルに特定のパッケージ用のリソースが含まれている場合は、当該バンドルにパッケージと同じ名前を付けます。例: controls、{formatters}}、validators。
リソースキー名
小文字で綴りを開始し、以後の連語をキャメルケース方式で記述します。例: pm、dayNamesShort。
その他の命名規則
「object」は曖昧であるため、使用を避けるようにします。
「item」はデータアイテムであり、DisplayObjectではありません。
「renderer」は、データアイテムが表示できるDisplayObjectです。
「type」はAS3の型を示します。それ以外の場面では、「kind」を使用するようにします。
言語使用法
この節では、我々がActionScript 3の言語コンストラクトをどのように使用しているかを解説します。特に、1つのコンストラクトに対して複数の表現方法があるケースを取り上げています。
コンパイルオプション
オプションの{{-strict}}と{{-show-actionscript-warnings}}を使用してコンパイルを行います。 (これらはflex-config.xmlファイルのデフォルトです。)
プロパティベースのAPI
メソッドベースのAPIではなく、プロパティベースのAPIを使用するようにします。後者の方が宣言言語型のMXMLプログラミングに適しているからです。
型宣言
すべての定数、変数、関数引数、関数の戻り値に対して、型宣言を記述するようにします。たとえ、単に「型なし」を示す「*」を記述するとしても、この規則が適用されます。
正しい記述例:
var value:*;
誤った記述例:
var value;
適用範囲が最も限定された型を使用するようにします。 たとえば、ループのインデックスには{{int}}を使用し、Number、あるいは間違っても{{Object}}や{{*}}を使わないようにしてください。 また、{{mouseDownHandler}}であれば、その引数には{{event:Event}}ではなく、{{event:MouseEvent}}を宣言するようにします。
整数の場合は、たとえ負になり得ないとしても{{int}}を使用します。 {{uint}}は、RGBカラーやビットマスク、もしくは他の非数値的な値のみに使用するようにします。
{}は、値が{{undefined}}になり得る場合に限り使用するようにします。 一般的には、{{null}}を「オブジェクトが存在しない」値として扱い、{}の代わりに{{Object}}を使用するようにします。
{{Array}}データ型を宣言する場合は、{{/* of ElementType */}}の体裁のコメントを{{Array}}直後に記述し、配列要素の型を示すようにします。 将来バージョンの言語では、型付けされた配列が含まれる見込みです。
正しい記述例:
var a:Array /* of String */ = [];
誤った記述例:
var a:Object = {}
正しい記述例:
function f(a:Array /* of Number */):Array /* of Object */
{
...
}
誤った記述例:
function f(a:Array):Array
リテラル
undefined
できる限り使用を避けるようにします。 undefinedは、コンパイル時の型が{}である値を扱う場合に限り必要となります。{}を多用することは望ましくありません。
{{int}}および{{uint}}リテラル
整数では小数点を使用しません。
正しい記述例:
2
誤った記述例:
2.
16進法の数値では小文字の{{x}}と大文字の{{A-Z}}を使用します。
正しい記述例:
0xFEDCBA
誤った記述例:
0Xfedcba
RGBカラーは、常に6桁の16進数で記述します。
正しい記述例:
private const BLACK:uint = 0x000000;
誤った記述例:
private const BLACK:uint = 0;
インデックスを扱う際には、「インデックスなし」を値の{{-1}}で表現できます。
{{Number}}リテラル
数値が小数値になることが一般的なケースでは、これを示す目的で小数点とその直後に1つのゼロを記述するようにします。
正しい記述例:
alphaFrom = 0.0; alphaTo = 1.0;
誤った記述例:
alphaFrom = 0; alphaTo = 1;
ただし、ピクセル座標を表現する場合は、原則として小数値が可能ではあるものの、慣習的な観点から整数を使用するようにします。
正しい記述例:
var xOffset:Number = 3;
誤った記述例:
var xOffset:Number = 3.0;
指数表現を用いる場合は、{{E}}ではなく{{e}}を使用します。
正しい記述例:
1.0e12
誤った記述例:
1.0E12
{{Number}}の「非設定」値としては、デフォルト値の{{NaN}}を使用します。
{{String}}リテラル
文字列の区切りとしては、たとえその文字列にクオーテーションマークが文字として含まれている場合でも、アポストロフィ(1重引用符)ではなくクオーテーションマーク(2重引用符)を使用します。
正しい記述例:
"What's up, \"Big Boy\"?"
誤った記述例:
'What\'s up, "Big Boy"?'
Unicodeエスケープシーケンスとしては、{{\U}}ではなく{{\u}}を使用します。
{{Array}}リテラル
{{new Array()}}ではなく、配列リテラルを使用するようにします。
正しい記述例:
[]
誤った記述例:
new Array()
正しい記述例:
[ 1, 2, 3 ]
誤った記述例:
new Array(1, 2, 3)
Arrayコンストラクタは、{{new Array(3)}}といったように、要素数を規定して配列を生成する時にだけ使用するようにします。この配列は{{[ undefined, undefined, undefined ]}}を意味するものであり、{{[ 3 ]}}ではありません。
{{Object}}リテラル
{{new Object()}}ではなく、Objectリテラルを使用するようにします。
正しい記述例:
{}
誤った記述例:
new Object()
正しい記述例:
o = { a: 1, b: 2, c: 3 };
誤った記述例:
o = new Object(); o.a = 1; o.b = 2; o.c = 3;
誤った記述例:
o = {};
o.a = 1;
o.b = 2;
o.c = 3;
{{Function}}リテラル
functionリテラルを使用して、匿名関数を定義することを避けるようにします。代わりに、クラスメソッドまたはパッケージ関数を使用するようにします。
functionリテラルの使用が避けられない場合は、戻り値の型を宣言するとともに、function部分の最後のステートメント直後にセミコロンを記述します。
正しい記述例:
function(i:int):void { doIt(i - 1); doIt(i + 1); }
誤った記述例:
function(i:int) { doIt(i - 1); doIt(i + 1) }
{{RegExp}}リテラル
{{String}}から{{RegExp}}インスタンスを生成するのではなく、リテラル表現を使用するようにします。
正しい記述例:
var pattern:RegExp = /\d+/g;
誤った記述例:
var pattern:RegExp = new RegExp("\\d+", "g");
{{XML}}リテラルおよび{{XMLList}}リテラル
{{String}}から{{XML}}インスタンスを生成するのではなく、リテラル表現を使用するようにします。
正しい記述例:
var node:XML = <name first="Jane" last="Doe"/>;
誤った記述例:
var node:XML = new XML("<name first=\"Jane\" last=\"Doe\"/>");
次の例にあるように、XML属性値の前後には1重引用符ではなく2重引用符を記述します。
正しい記述例:
var node:XML = <name first="Jane" last="Doe"/>;
誤った記述例:
var node:XML = <name first='Jane' last='Doe'/>;
{Class}}リテラル
インポートされた同一非限定名の2つのクラスが混乱するのを避ける必要がある場合に限り、完全限定的なClassリテラルを使用します。
正しい記述例:
import mx.controls.Button; ... var b:Button = new Button();
誤った記述例:
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();
表現
括弧
+、-、*、/、&&、||、<、<=、>、>=、==、!=といった一般的な演算子を使用する際に、不必要な括弧を記述しないようにします。
正しい記述例:
var e:Number = a * b / (c + d);
誤った記述例:
var e:Number = (a * b) / (c + d);
正しい記述例:
var e:Boolean = a && b || c == d;
誤った記述例:
var e:Boolean = ((a && b) || (c == d));
他の演算子の優先規則は覚えやすくないものがあるので、括弧の使用が有用なこともあります。
強制
ブール値を{{true}}または{{false}}と比較するのは避けます。ブール値は、すでにいずれかの値です。
正しい記述例:
if (flag)
誤った記述例:
if (flag == true)
正しい記述例:
var flag:Boolean = a && b;
誤った記述例:
var flag:Boolean = (a && b) != false;
int、uint、{{Number}}および{{String}}は明示的に{{Boolean}}に強制します。
正しい記述例:
if (n != 0)
誤った記述例:
if (n)
正しい記述例:
if (s != null && s != "")
誤った記述例:
if (s)
オブジェクト参照は暗示的にブール値に強制します。
正しい記述例:
if (child)
誤った記述例:
if (child != null)
正しい記述例:
if (!child)
誤った記述例:
if (child == null)
{{as}}演算子より、キャストの使用を優先するようにします。 {{as}}演算子は、強制に失敗する恐れがあるケースで、例外が発生する代わりに表現式が{{null}}に評価されることを望む場合にのみ使用します。
正しい記述例:
IUIComponent(child).document
誤った記述例:
(child as IUIComponent).document
比較
比較は、最も自然に読める順序で記述します。
正しい記述例:
if (n == 3) // "nが3の場合"
誤った記述例:
if (3 == n) // "3がnの場合"
{{++}}演算子と{{--}}演算子
演算子を後付けにするのと前付けにするのが対等である場合は、後付けの書式を使用します。 前付けの書式は、増減が行われる前に値を使用しなければならない場合に限り使用します。
正しい記述例:
for (var i:int = 0; i < n; i++)
誤った記述例:
for (var i:int = 0; i < n; ++i)
三項演算子
単純な{{if}}/{{else}}文の代わりに三項演算子を使用するようにします。この規則は、特に{{null}}をチェックする際に当てはまります。
正しい記述例:
return item ? item.label : null;
誤った記述例:
if (!item)
return null;
return item.label;
ただし、複合的な{{if}}/{{else}}文の代わりに、入れ子状の三項演算子を使用するのは避けるようにします。
正しい記述例:
if (a < b)
return -1;
else if (a > b)
return 1;
return 0;
誤った記述例:
return a < b ? -1 : (a > b ? 1 : 0);
{new}}演算子
たとえコンストラクタに引数がない場合でも、クラス参照の直後には括弧を記述します。
正しい記述例:
var b:Button = new Button();
誤った記述例:
var b:Button = new Button;
ステートメント
各ステートメントはセミコロンで終了します。 ActionScript 3のオプションのセミコロン機能は、使用しないようにします。
正しい記述例:
a = 1; b = 2; c = 3;
誤った記述例:
a = 1 b = 2 c = 3
{{include}}ステートメント
使用が廃止されている{{#include}}ではなく{{include}}を使用します。 includeステートメントは他のステートメント同様にセミコロンで終了します。
正しい記述例:
include "../core/ComponentVersion.as";
誤った記述例:
#include "../core/ComponentVersion.as"
絶対パスではなく、相対パスを使用します。
{{import}}ステートメント
*ワイルドカードを使用する代わりに、特定されたクラス、インタフェースおよびパッケージレベル関数をインポートするようにします。
正しい記述例:
import mx.controls.Button; import flash.utils.getTimer;
誤った記述例:
import mx.core.*;
{{use namespace}}ステートメント
使用を避けるようにします。代わりに非オープンな名前空間への各参照には、「::」シンタックスを使用します。
正しい記述例:
import mx.core.mx_internal; // 後に登場するメソッドでは... mx_internal::doSomething();
誤った記述例:
import mx.core.mx_internal; use namespace mx_internal; // 後に登場するメソッドでは... doSomething();
{{if}}ステートメント
if/elseステートメントの分岐後条件に単一のステートメントのみが含まれる場合は、これらをブロックにすることを避けます。
正しい記述例:
if (flag)
doThing1();
誤った記述例:
if (flag)
{
doThing1();
}
正しい記述例:
if (flag)
doThing1();
else
doThing2():
誤った記述例:
if (flag)
{
doThing1();
}
else
{
doThing2();
}
ただし、分岐後の条件部に複数のステートメントが含まれる場合は、すべてをブロックで記述します。
正しい記述例:
if (flag)
{
doThing1();
}
else
{
doThing2();
doThing3();
}
誤った記述例:
if (flag)
doThing1();
else
{
doThing2();
doThing3();
}
複数のエラーチェックを行う場合は、失敗を判定するためのifステートメントを連続的に配置し、できるだけ早くreturnが起こるようにします。 成功時の実行フローではページの下部まで達し、当該メソッドの最後でreturnが返されます。 成功判定のために入れ子状の検証を行うと、実行フローがページ内をさまようことになります。このような記述は避けるようにします。
正しい記述例:
if (!condition1)
return false;
...
if (!condition2)
return false;
...
if (!condition2)
return false;
...
return true;
誤った記述例:
if (condition1)
{
...
if (condition2)
{
...
if (condition3)
{
...
return true;
}
}
}
return false;
{{for}}ステートメント
たとえステートメントが1つしかない場合でも、{{for}}ループの命令部分はブロックで記述します。
正しい記述例:
for (var i:int = 0; i < 3; i++){
doSomething(i);
}
誤った記述例:
for (var i:int = 0; i < 3; i++)
doSomething(i);
{{for}}ループの上限値は、ループが処理されるたびに値が再評価されないよう、ローカル変数に格納します。(もちろん、各処理時に再評価の必要がある場合は、この限りではありません。)
正しい記述例:
var n:int = a.length;
for (var i:int = 0; i < n; i++)
{
...
}
誤った記述例:
for (var i:int = 0; i < a.length; i++)
{
...
}
ループのvarの宣言は、それ自体が別の場所で再利用されていない限り{{for}}ステートメントの括弧内で行います。
正しい記述例:
for (var i:int = 0; i < 3; i++)
誤った記述例:
var i:int;
for (i = 0; i < 3; i++)
{
...
}
{{while}}ステートメント
たとえステートメントが1つしかない場合でも、{{while}}ループの命令部分はブロックで記述します。
正しい記述例:
while (i < n)
{
doSomething(i);
}
誤った記述例:
while (i < n)
doSomething(i);
{{do}}ステートメント
たとえステートメントが1つしかない場合でも、{{do}}ループの命令部分はブロックで記述します。
正しい記述例:
do
{
doSomething(i);
}
while (i < n);
誤った記述例:
do
doSomething(i);
while (i < n);
{{switch}}ステートメント
各{{case}}句の内容、および{{default}}句の内容はブロックで記述します。 {{break}}ステートメントおよび{{return}}ステートメントは、ブロックの後ではなくブロック内に記述します。 returnがある場合は、{{return}}を{{break}}の後に配置しないようにします。 default句はcase句同様に扱うようにし、{{break}}や{{return}}を記述して{{switch}}の最後まで処理が達するのを防ぐようにします。
正しい記述例:
switch (n)
{
case 0:
{
foo();
break;
}
case 1:
{
bar();
return;
}
case 2:
{
baz();
return;
}
default:
{
blech();
break;
}
}
誤った記述例:
switch (n)
{
case 0:
foo();
break;
case 1:
{
bar();
}
break;
case 2:
baz();
return;
break;
default:
blech();
}
{{return}}ステートメント
戻り値を余分な括弧で囲むのを避けるようにします。
正しい記述例:
return n + 1;
誤った記述例:
return (n + 1);
メソッドの途中でリターンするのは問題ありません。
宣言
複数の定数および変数を1つの宣言文で宣言することは避けます。
正しい記述例:
var a:int = 1; var b:int = 2;
誤った記述例:
var a:int = 1, b:int = 2;
{{override}}キーワード
このキーワードを使用する場合は、アクセス指定子より前の、文の最初に記述します。
正しい記述例:
override protected method measure():void
誤った記述例:
protected override method measure():void
アクセス指定子
アクセス指定子が許可されている場面では、必ずアクセス指定子を明示します。 アクセス指定子が記述されていない場合は、暗示的に{{internal}}と解釈されることに頼らないようにしてください。
APIを{{public}}または{{protected}}にする際には、その必要性を十分に検討するようにします。 publicおよびprotectedのAPIに対しては、ドキュメンテーションを用意する必要があります。 また、これらを廃止する際には、あらかじめ数リリース前まで遡ってサポートを提供する必要があります。
{{static}}キーワード
このキーワードを使用する場合は、アクセス指定子の後に記述します。
正しい記述例:
public static const MOVE:String = "move"
誤った記述例:
static public const MOVE:String = "move";
{{final}}キーワード
このキーワードを使用する場合は、アクセス指定子の後に記述します。
正しい記述例:
public final class BoxDirection
誤った記述例:
final public class BoxDirection
enumクラスはすべてfinalとして宣言します。
また、({{$}}で始まる)ベースのプロパティやメソッドもfinalとして宣言します。
定数
定数はすべてstaticにするようにします。 instance定数では、すべてのインスタンスで同じ値が用いられます。したがって、instance定数を使用する理由はありません。
正しい記述例:
public static const ALL:String = "all";
誤った記述例:
public const ALL:String = "all";
変数
変数をデフォルト値以外で初期化したい場合は、コンストラクタでではなく宣言でこれを行うようにします。
正しい記述例:
private var counter:int = 1;
誤った記述例:
private var counter:int;
...
public function MyClass()
{
super();
...
counter = 1;
}
ローカル変数
ローカル変数は、その変数が初めて使用される時点、または使用される直前に宣言するようにします。 すべての宣言を関数の最初の部分に記述することは避けます。
正しい記述例:
private function f(i:int, j:int):int
{
var a:int = g(i - 1) + g(i + 1);
var b:int = g(a - 1) + g(a + 1);
var c:int = g(b - 1) + g(b + 1);
return (a * b * c) / (a + b + c);
}
誤った記述例:
private function f(i:int, j:int):int
{
var a:int;
var b:int;
var c:int;
a = g(i - 1) + g(i + 1);
b = g(a - 1) + g(a + 1);
c = g(b - 1) + g(b + 1);
return (a * b * c) / (a + b + c);
}
ローカル変数は、1つの関数内で1度だけ宣言するようにします。 ActionScript 3はブロックス有効範囲のローカル変数に対応していません。
正しい記述例:
var a:int;
if (flag)
{
a = 1;
...
}
else
{
a = 2;
...
}
誤った記述例:
if (flag)
{
var a:int = 1;
...
}
else
{
var a:int = 2;
...
}
正しい記述例:
var i:int;
for (i = 0; i < n; i++)
{
...
}
for (i = 0; i < n; i++)
{
...
}
誤った記述例:
for (var i:int = 0; i < n; i++)
{
...
}
for (var i:int = 0; i < n; i++)
{
...
}
クラス
あるクラスが{{Object}}を単に拡張するのであれば、{{extends Object}}句は省略します。
クラス内の「ベアステートメント」のみが、({{loadResources()}}などの)静的クラス初期化メソッドの呼び出しになるようにします。
コンストラクタ
クラスにインスタンスメンバが含まれる場合はコンストラクタを記述して、たとえ他の用途がないとしても明示的に{{super()}}を呼び出すようにします。
インスタンスの変数に渡す引数がコンストラクタに含まれるのであれば、そのインスタンス変数と同じ名前を付けるようにします。
正しい記述例:
public function MyClass(foo:int, bar:int)
{
this.foo = foo;
this.bar = bar;
}
誤った記述例:
public function MyClass(fooVal:int, barVal:int)
{
foo = fooVal;
bar = barVal;
}
コンストラクタ内でクラスのインスタンス変数を設定することは避けるようにします。値の設定はインスタンス変数の宣言時に行います。 ただし、継承したインスタンス変数の値をリセットしなければならない場合は、この操作をコンストラクタ内で行います。
インタフェース
後日発表予定
名前空間
後日発表予定
プロパティの実装
後日発表予定
メタデータ
後日発表予定
パッケージ
パッケージステートメント内では、1つのpublic API (通常はクラス、場合によっては名前空間または関数)のみを配置します。
ヘルパークラス
ベアステートメント
ファイル構成
この節では、Flexフレームワークファイルのファイル構成順序を説明します。
著作権表記
フレームワークのすべての.asファイルの上部に著作権表記を含めます。 以下に、2008年のオープンソース著作権情報の書式を示します。
//////////////////////////////////////////////////////////////////////////////// // // ADOBE SYSTEMS INCORPORATED // Copyright 2008 Adobe Systems Incorporated // All Rights Reserved. // // NOTICE: Adobe permits you to use, modify, and distribute this file // in accordance with the terms of the license agreement accompanying it. // ////////////////////////////////////////////////////////////////////////////////
幅が80文字である点に注意してください。
packageステートメント
後日発表予定
importステートメント
後日発表予定
use namespaceステートメント
後日発表予定
クラスメタデータ
クラスのメタデータはセクションに分類し、Events、Styles、Effects、Excluded APIs、Other Metadataの順に記述します。
各セクションの前には二次セクションヘッダを配置します。 二次セクションヘッダの幅は40文字。そして、「//」とセクション名の間には半角スペースが2つ入っていることに注意してください。
各セクション内ではメタデータのname="..."の部分を基準にアルファベット順に並べます。 Other Metadata(その他のメタデータ)セクションでは、メタデータのタグ名を基準にアルファベット順に並べます。
//-------------------------------------- // Events //-------------------------------------- / ** * ASDoc comment. */ [Event /** * ASDoc comment. */ [Event //-------------------------------------- // Styles //-------------------------------------- /** * ASDoc comment. */ [Style /** * ASDoc comment. */ [Style] //-------------------------------------- // Effects //-------------------------------------- /** * ASDoc comment. */ [Effect /** * ASDoc comment. */ [Effect] //-------------------------------------- // Excluded APIs //-------------------------------------- [Exclude(name="horizontalAlign", kind="style")] [Exclude(name="verticalAlign", kind="style")] //-------------------------------------- // Other metadata //-------------------------------------- [DefaultBindingProperty(source="text", destination="text")] [IconFile("Text.png")]
クラス宣言
後日発表予定
Version.as用のincludeステートメント
クラスには相対パスを使用して、core/Version.asをインクルードするようにします。 このファイルには{{static const VERSION:String}}の宣言が含まれています。
include "../core/Version.as";
実装に関するメモ
後日発表予定
クラスの初期化
後日発表予定
クラス定数
{{static const}}宣言をここに配置します。
ActionScript 3では、{{Array}}型または{{Object}}型の定数は許可されていません。 このようなケースでは{{static const}}ではなく{{static var}}で定数を宣言します。ただし、この場合、概念上は定数であるため、このセクションに記述するようにします。
クラスミックスイン
メソッドとして宣言されるのではなく、ミックスインされるような{{Function}}型のstatic変数は、すべて宣言するようにします。
クラスリソース
後日発表予定
クラス変数
後日発表予定
クラスプロパティ
static getterおよびstatic setterはここで宣言するようにします。 これらの宣言はプロパティ名を基準にアルファベット順に並べます。 各プロパティ間には、プロパティ名の入った二次的なセパレータを配置します。 getterを記述してからsetterを記述するようにします。
クラスメソッド
{{static function}}宣言をここに配置します。
コンストラクタ
後日発表予定
変数
後日発表予定
オーバーライドされたプロパティ
非staticのgetterおよびsetterのオーバーライドをここに配置します。 これらの宣言はプロパティ名を基準にアルファベット順に並べます。 各プロパティ間には、プロパティ名の入った二次的なセパレータを配置します。 getterを記述してからsetterを記述するようにします。
プロパティ
新たな非staticのgetterおよびsetterをここに配置します。 これらの宣言はプロパティ名を基準にアルファベット順に並べます。 各プロパティ間には、プロパティ名の入った二次的なセパレータを配置します。 getterを記述してからsetterを記述するようにします。
オーバーライドされたメソッド
非static関数のオーバーライドをここに配置します。
メソッド
新たな非static関数をここに配置します。
オーバーライドされたイベントハンドラ
イベントハンドラのオーバーライドをここに配置します。
イベントハンドラ
新たなイベントハンドラをここに配置します。
パッケージ外のヘルパークラス
後日発表予定
記述書式
この節では、Flexフレームワーククラスの書式について説明します。
行あたりの幅
コードは1行あたり半角文字80字で折り返します。 これにより以下のメリットを享受できます。
- デベロッパーが小さな画面を使用している場合でも、長い行を読む際に水平にスクロールする必要がありません。
- 比較ユーティリティを使用する際、ファイルの2つのバージョンを並べて表示できます。
- プロジェクタを使用してグループにプレゼンする際、スクロールではなくフォントサイズを大きくすることで対応できます。
- 途切れや無駄な改行なく、ソースコードを印刷できます。
インデント
半角スペース4文字のインデントを使用します。 テキストエディタの設定を調整し、タブではなくスペースが挿入されるようにします。 この規則を守ることで、他のインデント設定が用いられたプログラム(8文字インデントのメモ帳など)でもコードの体裁を乱すことなく表示できるようになります。
セクションセパレータ(区切り)
クラス内の主要セクションセパレータは次の体裁にします。
//--------------------------------------------------------------------------
//
// Overridden methods
//
//--------------------------------------------------------------------------
セパレータ自体を4文字目から80文字目まで延ばし、テキストを8文字目までインデントします。
クラス内の二次セクションセパレータ(プロパティ間など)は次の体裁にします。
//----------------------------------
// visible
//----------------------------------
セパレータ自体を4文字目から40文字目まで延ばし、テキストを8文字目までインデントします。
セパレータの前後には空白行をそれぞれ1行配置します。
宣言の分離
定数、変数および関数宣言の間には、縦方向のセパレータとして空白行を1行配置します。
/** * @private * Holds something. */ var a:Number; /** * @private */ var b:Number
メタデータ
後日発表予定
正しい記述例:
Inspectable[a="1", b="2"]
誤った記述例:
Inspectable[a=1 b=2]
配列のインデックス
左側の角括弧の直前、直後、および右側の角括弧の直前には半角スペースを入れません。
正しい記述例:
a[0]
誤った記述例:
a[ 0 ]
カンマ
カンマの後には半角スペースを1つ記入します。 この規則は一連の引数、arrayリテラルおよびobjectリテラルに適用されます。
Arrayリテラル
左側の角括弧の直後に半角スペースを1つ、右側の角括弧の直前にも半角スペースを1つ、そして各カンマの直後(直前ではありません)に半角スペースを1つそれぞれ配置します。
正しい記述例:
[ 1, 2, 3 ]
誤った記述例:
[1, 2, 3] [1,2,3]
空の配列は特殊なケースとして扱われます。
正しい記述例:
[]
誤った記述例:
[ ]
複数の行が必要となるような長い配列の初期化時には、整列された角括弧を使用します。
static var numberNames:Array /* of String */ =
[
"zero",
"one",
"two",
"three",
"four",
"five",
"six",
"seven",
"eight",
"nine"
];
Objectリテラル
左側の波括弧の直後に半角スペースを1つ、右側の波括弧の直前にも半角スペースを1つ、そしてプロパティ名とその値を分けるコロンの直後に半角スペースを1つ配置するようにします。
正しい記述例:
{ a: 1, b: 2, c: 3 }
誤った記述例:
{a: 1, b: 2, c: 3}
{a:1, b:2, c:3}
{a:1,b:2,c:3}
空のオブジェクトは特殊なケースとして扱われます。
正しい記述例:
{}
誤った記述例:
{ }
複数の行が必要となるような長いオブジェクトの初期化時には、整列された波括弧を使用します。
private static var TextStyleMap:Object =
{
color: true,
fontFamily: true,
fontSize: true,
fontStyle: true,
fontWeight: true,
leading: true,
marginLeft: true,
marginRight: true,
textAlign: true,
textDecoration: true,
textIndent: true
};
関数リテラル
後日発表予定
var f:Function;
f = function():void
{
doSomething();
};
型宣言
変数、引数または関数とこれらの型の間にあるコロンの直前および直後には半角スペースを入れません。
正しい記述例:
var n:Number;
誤った記述例:
var n : Number; var n: Number;
正しい記述例:
function f(n:Number):void
誤った記述例:
function f(n : Number) : void function f(n: Number): void
演算子と代入
代入演算子の前後には半角スペースを1つ入れます。
正しい記述例:
a = 1;
誤った記述例:
a=1;
Infix演算子の前後には半角スペースを1つ入れます。
正しい記述例:
a + b * c
誤った記述例:
a+b*c
比較演算子の前後には半角スペースを1つ入れます。
正しい記述例:
a == b
誤った記述例:
a==b
Prefix演算子とその作用対象の間にはスペースを入れません。
正しい記述例:
!o
誤った記述例:
! o
Postfix演算子とその作用対象の間にはスペースを入れません。
正しい記述例:
i++
誤った記述例:
i ++
ステートメント
すべてのステートメントにブレークポイントを設置できるよう、各ステートメントを新たな行で開始するようにします。
正しい記述例:
a = 1; b = 2; c = 3;
誤った記述例:
a = 1; b = 2; c = 3;
ステートメントブロックの括弧を整列するようにします。
正しい記述例:
function f():void
{
var n:int = numChildren;
for (var i:int = 0; i < n; i++)
{
if ()
{
x = horizontalGap * i;
y = verticalGap * i;
}
}
}
誤った記述例:
function f():void {
var n:int = numChildren;
for (var i:int = 0; i < n; i++) {
if () {
x = horizontalGap * i;
y = verticalGap * i;
}
}
}
定数および変数の宣言
後日発表予定
関数の宣言
後日発表予定
正しい記述例:
f(a, b)
誤った記述例:
f(a,b) f( a, b )
引数を列挙する際に行の折り返しが発生する場合は、左側の括弧と整列するように折り返し後の行をインデントします。 スペースに余裕がある場合は複数の引数を1行に記述し、それ以外の場合は1行につき1つの引数を記述します。 1つの引数さえ記述するスペースがない場合は、2行目に最初の引数を配置し、この行のインデントを関数名より前の位置にまで移動します。
public function foo(parameter1:Number, parameter2:String,
parameter3:Boolean):void
public function foo(parameter1:Number,
parameter2:String,
parameter3:Boolean):void
public function aVeryLongFunctionName(
parameter1:Number, parameter2:String,
parameter3:Boolean):void
関数の呼び出し
後日発表予定
正しい記述例:
f(a, b)
誤った記述例:
f(a,b) f( a, b )
{{if}}ステートメント
{{if}}キーワードと左側の括弧の間には半角スペースを1つ入れます。 左側の括弧の直後、および右側の括弧の直前には半角スペースを入れません。
正しい記述例:
if (a < b)
誤った記述例:
if(a < b) if( a < b ) if ( a < b )
else if ?
multiline ?
{{for}}ステートメント
{{for}}キーワードと左側の括弧の間には半角スペースを1つ入れます。 左側の括弧の直後、および右側の括弧の直前には半角スペースを入れません。
正しい記述例:
for (var i:int = 0; i < n; i++)
誤った記述例:
for(var i:int = 0; i < n; i++) for( var i:int = 0; i < n; i++ ) for ( var i:int = 0; i < n; i++ )
{{for}}句で行の折り返しが発生する場合は、左側の括弧と整列するように折り返し後の行をインデントします。
for (var aLongLoopVariableName:int = aLongInitialExpression;
aLongLoopVariableName < aLongUpperLimit;
aLongLoopVariableName++)
<a name="CodingConventions-%7B%7Bswitch%7D%7Dstatements"></a>{{switch}}ステートメント
{{switch}}キーワードと左側の括弧の間には半角スペースを1つ入れます。 左側の括弧の直後、および右側の括弧の直前には半角スペースを入れません。
正しい記述例:
switch (n)
誤った記述例:
switch(n) switch( n ) switch ( n )
{{switch}}キーワードと左側の括弧の間には半角スペースを1つ入れます。 左側の括弧の直後、および右側の括弧の直前には半角スペースを入れません。
正しい記述例:
switch (n)
{
case 1:
{
a = foo();
break;
}
case 2:
{ a = bar();
break;
}
default:
{
a = blech();
break;
}
}
誤った記述例:
switch(n) switch( n ) switch ( n )
{{class}}宣言および{{interface}}宣言
括弧を常に対応させるようにします
単独の行の周囲に括弧は不要です
1行につき1つのステートメントを記述します
ASDoc
プロパティに対するコメント付け
プロパティにある一対のget/set関数のうち、最初のものにだけコメントを付けるようにします。 プロパティの定義方法およびコメント記述体裁は以下の通りです。
/**
* @private
* The backing variable for the property.
*/
private var _someProp:Foo;
/**
* Place all comments for the property with the getter which is defined first.
* Comments should cover both get and set behavior as appropriate.
*/
public function get someProp():Foo
{
...
}
/**
* @private
*/
public function set someProp(value:Foo):void
{
...
}
ASDocのコメントはメタデータタグだけでなく、クラス内の他のコンストラクトにも適用されます。コメントが、対象となるすべてにとって適切であるよう注意してください。 プロパティをBindableとしてタグ化する場合は、プロパティコメントをget関数より前かつBindableメタデータタグより後ろの位置に配置します。
正しい記述例:
[Bindable("somePropChanged")] /** * Comments for someProp */ public function get someProp():Foo
誤った記述例:
/** * Comments for someProp */ [Bindable("somePropChanged")] public function get someProp():Foo