Coding Conventions

AS3コーディング規約の有名なものに、Adobe Open Sourceで公開されているFlex SDK Conventionsがあります。日本語訳版もあります。このコーディング規約を尊重する方向で、自分なりのコーディング規約を探ってみました。

なお、Flex SDK Conventionsは

ActionScript 3でオープンソースFlexフレームワークコンポーネントを記述する際のコーディング規則

と、あるとおりAS3を書く際の絶対的なコーディング規約ではありませんのでご注意を。

セクション

さて、Flex SDK Conventionsは下記のセクションに分かれているようです。

  1. 命名規約
  2. コーディング規約
  3. asファイル構成規約
  4. 記述書式規約
  5. ASDoc規約

命名規則は、変数や関数などの名付けルール。コーディング規約は、コーディング時のルール。asファイル構成規約は、1つのasファイル内の構成ルール。記述書式規約では、スペースやTABにまつわる所謂細かいルール。ASDoc規約は、ASDocの簡単な紹介といった感じです。

各セクションから、これはいいな、と思った規約をピックアップしていこうと思います。

命名規約

  1. 短縮形は一般的なもの(auto, info, min, max, utilのような)以外使わない。
  2. 頭字語の綴りは、必ず大文字または小文字のいずれかで統一する。
  3. 単語の区切りは、キャメルケース、アンダースコアスタイルを使い分ける(後述の表1を参照)
  4. AS1, AS2時代の_btn, _mcといった変数名の付け方を避ける。
  5. setterの引数はvalueで統一する。
  6. event handlerの引数はeventで統一する。

ざっと、こんな感じです。キャメルケースの説明は以下が参考になります。

キャメルケース(英:CamelCase)とは、複合語をひと綴りとして、要素語の最初を大文字で書き表すことをいう。キャメルケースとは、大文字が「らくだのこぶ」のように見えることからの命名である。 キャメルケース

単語の区切りは、キャメルケース、アンダースコアスタイルを使い分ける、という部分は表にまとめました。 以下の表では、複合語の先頭を、大文字で書き始めるキャメルケースをUCC(Upper Camel Case)、複合語の先頭を、小文字で書き始めるキャラメルケースをLCC(Lower Camel Case)と記載しました。

表1. コンテキストによる命名規則の使い分け
コンテキストスタイル
package小文字(名詞)package la.fla.blog
namespaceアンダースコアnamespace mx_internal
interface先頭I + キャメル(UCC)IEventDispatcher
classキャメル(UCC)class Main
event nameキャメル(LCC)public static const EVENT_COMPLETE:String = "eventComplete";
const大文字でアンダースコアpublic static const IMAGE_HOST:String = "http://example.com";
private propertyアンダースコア + キャメル(LCC)private var blogSetting:Object = {};
other propertyキャメル(LCC)private var blogSetting:Object = {};
methodキャメル(LCC)public function checkLength():void{};
event handlerthisから送出されるイベントの場合は キャメル(LCC)でイベント名 + Handler
this以外はプロパティ名 + アンダースコア + キャメル(LCC)でイベント名 + Handler
loaderInfo_completeHandler

Flex SDK Convensionsとの相違点を整理

Flex SDK Conventionsでは、パッケージ名の命名規則は、キャメル(LCC)となっています。しかし、複数単語の単語で構成するパッケージはパッケージの分け方に問題があるのではないかと思います。出来る限り1単語でパッケージを分けることが好ましいのではないでしょうか(偉そう)。

コーディング規約

  • プロパティベースのAPIを使う(getNext()というmethodではなく、getterでnextを作る)
  • 型宣言は省略しない
  • 16進数は小文字のxと数値、大文字のA~Fで記述する(0xFFCC00)
  • RGBカラー指定は桁数を略さない(0x000000)
  • 小数を期待する場合は.0を明示的に(alpha = 1.0)
  • 座標は出来る限り整数で指定(x = 100)
  • Stringはシングルクォーテーションではなく、ダブルクォーテーションで括る("Hello world.")
  • new Array()は[]で記述
  • new Object()は{}で記述
  • new RegExp()は//で記述(変数を使う場合はnew RegExp())
  • new XML(), new XMLListはで記述
  • Functionをリテラル記述する際、一行でも;を記述。型宣言を記述。
  • Boolean型の変数とtrue, falseを比較しない(if (flg)やif (!flg)で判定)
  • Number型の変数は明示的に比較するif (number == 0)
  • 型変換はasよりもキャストを使う
  • 等号は変数を左辺に記述する
  • 不等号は<で統一
  • イクリメントは基本ポストインクリメント(hoge++)
  • null判定は三項演算子を使う
  • new演算子を使う場合はクラス名の後ろの()を省略しない
  • include文に#を付けない
  • use namespaceを使い、他のネームスペースを省略して書くことを避ける
  • if文に含まれる処理が1行である場合は{}を省略する
  • if文でなるべくはやくreturn falseする
  • switch文ではcaseごとに{}で囲う
  • overrideは他のアクセス指示子より先に記述する
  • internalでもinternalアクセス指示子を省略しない
  • static, finalは他のアクセス指示子より後に記述する
  • 定数はstatic変数で定義する
  • 変数の初期化はコンストラクタではなく宣言時に行う
  • ローカル変数は初めて使う場所で宣言する(あらかじめ関数の最初に宣言しない)
  • コンストラクタでインスタンスメンバーを初期化する場合は同名変数を引数にする(代入時にはthisを用いて区別)

Flex SDK Convensionsとの相違点を整理

ArrayやObjectの書き方は

var monthNameList:Array = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ];

という風に[の後と]の前にスペースを空けましょうとのことだったのですが

var weekNameList:Array = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"];

とした方がしっくり来るんですよね。なので、省きました。

importのワイルドカードは使うと便利なことが多いので、何をインポートするか分かりきっている場合には使っていいじゃないかと思い、省きました。

asファイル構成規約

  1. ライセンスを明記
  2. package宣言
  3. import文
  4. use namespace文(どうしても使いたい場合)
  5. Eventsメタデータ ASDoc用に書いておく
  6. class宣言
  7. static定数、変数
  8. staticメソッド(static初期化ブロック)
  9. instance定数、変数
  10. instanceメソッド(コンストラクタ)
  11. イベントハンドラ
  12. ヘルパークラス(private Class)

アクセス指示子は

  1. public
  2. protected
  3. private

の順で記述します。後述するセパレータだけで記述すると以下のようになります。

package
{
    import flash.display.Sprite;
    /**
     * Event description
     * @type    flash.events.Event.INIT
     */
    [Event( name="init", type="flash.events.Event" )]

    public class HelloWorld extends Sprite
    {
        //----------------------------------------------------------------------
        //  static properties
        //----------------------------------------------------------------------
        //------------------------------
        //  public static properties
        //------------------------------

        //------------------------------
        //  private static properties
        //------------------------------

        //----------------------------------------------------------------------
        //  static methods
        //----------------------------------------------------------------------
        //------------------------------
        //  static initializer
        //------------------------------

        //------------------------------
        //  public static methods
        //------------------------------

        //------------------------------
        //  private static methods
        //------------------------------


        //----------------------------------------------------------------------
        //  properties
        //----------------------------------------------------------------------
        //------------------------------
        //  public properties
        //------------------------------

        //------------------------------
        //  protected properties
        //------------------------------

        //------------------------------
        //  private properties
        //------------------------------

        //----------------------------------------------------------------------
        //  methods
        //----------------------------------------------------------------------
        //------------------------------
        //  override methods
        //------------------------------

        //------------------------------
        //  public methods
        //------------------------------

        //------------------------------
        //  protected methods
        //------------------------------

        //------------------------------
        //  private methods
        //------------------------------

        //----------------------------------------------------------------------
        //  event handler
        //----------------------------------------------------------------------
        //------------------------------
        //  override event handler
        //------------------------------

        //------------------------------
        //  protected event handler
        //------------------------------

        //------------------------------
        //  private event handler
        //------------------------------
    }
}

Flex SDK Convensionsとの相違点を整理

Flex SDK Conventionsとは大分順序を変えています。

記述書式規約

  • 一行辺り最大80文字とする
  • インデントは半角スペース4文字
  • 区切りとして80文字幅のセパレータと40文字幅のセパレータを使用する
  • 定数、変数および関数宣言の間には、空白行を1行配置
  • 左側の角括弧の直前、直後、および右側の角括弧の直前には半角スペースを入れない。(list[0]とする)
  • カンマの後にはスペースを入れる([0, 1, 2])
  • 型宣言で:の間にスペースを入れない(var hoge:String)
  • 演算子と代入時にはスペースを入れる(var hoge:Number = 100)
  • インクリメント演算子ではスペースを入れない(hoge ++)
  • !演算子ではスペースを入れない(!flg)
  • 1行に複数ステートメントを記述しない
  • 関数呼び出し時に括弧の間にスペースを入れない(trace("a", "b"))
  • if, for, while, switchではステートメントの後ろにはスペースを入れるが(の後と)の前にスペースを入れない

Flex SDK Convensionsとの相違点を整理

Flex SDK ConventionsでTBD(to be determined)となっているもの以外は、それなりにピックアップしたつもりです。

ASDoc規約

Read OnlyプロパティとWrite Onlyプロパティ、publicプロパティによって記述方法が異なります。

Read Onlyプロパティ

private var _userName:String = "guest";
/**
 * プロパティの説明を記述します。
 */
public function get userName():String
{
    return _userName;
}

Write Onlyプロパティ

private var _userName:String = "guest";
/**
 * プロパティの説明を記述します。
 */
public function set userName(value):void
{
    _userName = value;
}

publicプロパティ

private var _userName:String = "guest";
/**
 * プロパティの説明を記述します。
 */
public function get userName():String
{
    return _userName;
}
/** @private */
public function set userName(value):void
{
    _userName = value;
}

その他、ASDocのタグはAdobeのヘルプを参考にすると良いです。

Adobe Flex 3ヘルプ - ASDoc タグ

まとめ

今後コーディングする際の指針となる規約が整理出来ました。 fla.laブログで紹介するサンプルや、今後作成するライブラリでは今回考えた(パクッただけ)コーディング規約に沿って記述していこうと思います。