このブログで紹介しているように、いろいろなアプリで共通に使える機能を、少しずつ独自ライブラリ化しています。ライブラリの数が増えてきて、少し気になっていることがあります。今まではあまり考慮していなかった、命名ルールのことです。
今後もライブラリは増えるでしょうから、あとから区別しやすいように、クラス名などの命名ルールを考え直すことにしました。対象となるのは、ファイル名、クラス名、メソッド名、データ型名、変数名、定義値名などです。何と何を区別すべきなのか、どうしたら簡単に区別できるのか、いろいろと悩んで得た結論を紹介します。
まず最初は、何と何を区別するかです。普通に考えて出てくるのは、共通ライブラリとアプリ独自の区別でしょう。
でも良く考えると、ソースコードには他のものも含まれています。Swiftの予約語、iOSのAPIに含まれるクラス名やメソッド名、それ以外のライブラリなどです。これらを、自分が作ったもの(共通ライブラリとアプリ独自の両方)と区別したくなります。つまり、共通ライブラリ、アプリ独自の処理、その他の3つで区別するという結論になります。
この3つのうち、その他だけは、すでに名前が与えられています。自分で名前を変えることはできません。そうなると、共通ライブラリとアプリ独自処理の両方に命名ルールを決めて、その他と区別するのが現実的な方法でしょう。
命名ルールで区別する方法としては、参考になる前例がいくつかあります。もっとも有力なのは、名前の先頭に、共通の1文字または2文字を付ける方法です。iOS関連で挙げると、NSで始まる一連のクラス名でしょう。NSはNextStepの略で、iOSのもととなったNextStepのクラスから続いています。というわけで、私も同じように、先頭に共通の文字をつけて区別することにしました。
すでに使っているのは、zという文字です。共通ライブラリとして作ったクラスのインスタンスを入れる変数の一部では、先頭にzを付けています。日付関連ならzDate、ファイル関連ならzFilesと。zを選んだのは、zで始まる英語の言葉が少ないのが理由です。
区別するのは2つですから、文字がもう1つ必要です。いろいろ悩んだ結果、やはり言葉の数が少なそうなyを選びました。つまり、共通ライブラリにはzを、アプリ共通の処理にはyを使うということです。
具体的な文字が決まったので、命名ルールを順番に決めていきましょう。
まずはクラス名から。クラス名は大文字で始まるため、共通ライブラリでは、大文字のZを先頭に付けます。例えばPhotoSelectorなら、ZPhotoSelectorとするわけです。先頭のZの次も大文字にすることで、先頭のZが、名前とは違う特別な文字だと伝わりやすいでしょう。アプリ独自で使うクラスも同様に、先頭に大文字Yを付けます。
これらのクラスが混在すると、変数宣言でクラス名が現れたとき、先頭がZなら独自ライブラリのクラス、先頭がYならアプリ独自のクラス、その他はそれ以外のクラスと区別できます。それ以外にも先頭がZやYのものがあるので、絶対とは言えませんが、ほとんど問題にならないでしょう。
続いて、クラスのインスタンスを入れる変数名です。今まで、共通ライブラリでの変数名の一部には、先頭に小文字のzを付けていました。前述のzDateやzFilesです。この命名ルールのままで構わないので、これからも継続します。また、今まで付けていなかった変数名でも、先頭にzを付けるように変更します。
問題は、アプリ独自のクラスです。そのインスタンスを入れる変数名だけ、先頭に小文字のyを付けるのはどうでしょうか。たとえばyProductとか。確かに区別はできるものの、使いやすいかどうかは試してみないと分かりません。とりあえず試してみて、良かったら続け、さほど良くなかったら命名ルールなしに戻したいと思います。
続いて、メソッド名です。これは、クラスのインスタンスを入れた変数名と一緒に使います。その変数名が区別を含んでいるため、わざわざ区別を入れても、二重の情報になってしまいます。というわけで、特別な命名ルールは使いません。
今度は、enumなどに付けるデータ型の名前です。enumでデータ型を用意すると、決められた値しか入れられませんから、値のエラーチェックも不要になり、さらに読みやすさも向上したコードが作れます。大変便利で良く使っています。
今までは、あまり気にせずに名前を付けてきました。もしかしたら、似たような名前を作っているかも。また、これから作りそうな気もします。重複しないとともに、どこに所属しているのか明らかなほうが良いと考えました。所属する場所のほとんどは、それを使うクラスです。クラスとの関連性を示せたら良いでしょう。
そこで命名ルールは、クラス名の略号を数文字で表し、先頭に付けることにしました。その数文字ですが、最初の1文字だけが大文字で、それ以外は小文字にします。たとえば、ZPhotoSelectorクラスならZpsと略せ、それをデータ型の名前の先頭に付けます。もしデータ型の名前がZpsBtnTypeなら、ZPhotoSelectorクラスで使われている、ボタンのタイプを意味すると推測できます。Zで始まるため、ライブラリのクラスであることも分かります。
アプリ独自のクラスでも、同じ命名ルールを採用しましょう。Yで始まる数文字の略語を得て、データ型の先頭に付けます。
続いて、定義値の名前です。定義値というのは、最大値や固定値などに名前を付けて定義し、処理の外に出して、見つかりやすくするものです。後から変更しそうな値に適用します。C言語の時代から使われていて、すべて大文字で表現する名前がよく用いられます。
私の場合だけかもしれませんが、処理の外に出す目的以外でも使っています。共通で使うような値を、定義値として最初に用意し、アプリ全体で使ったりします。定義値を用意することで、名前による間接参照にもなりますし。
このような使い方なので、使う機会はかなり多いです。作った場所というか、持ち主が区別できると良いと思っています。
その命名ルールですが、ライブラリの場合は、先頭にZ_を付けることにしました。名前の全部が大文字なので、Zだけだと区切りが不明確になるからです。今までCOLOR_ERRORとしていたのを、今後はZ_COLOR_ERRORとします。
もう1つとなるアプリ独自の定義値の名前は、何も付けないことにしました。その他の分類で似たような定義値が使われていないようなので、ライブラリだけ区別すれば十分と考えたからです。先頭にZ_が付いていればライブラリの定義値、それ以外はアプリ独自の定義値と判断します。
最後は、ソースコードのファイル名です。これは以前に「管理しやすい分類情報付きファイル名を使おう」にて紹介しました。あれから分類が1つ増えたので、今では次のようになっています。
// ファイル名の先頭に付ける主な分類情報
・AC:特定の条件(装置など)に依存する共通ライブラリのクラス(複数アプリで利用)
・BP:共通ライブラリの関数や定義値など(複数アプリで利用)
・BV:共通ライブラリのクラスでUIView型(複数アプリで利用)
・BC:共通ライブラリのクラスでUIView型以外(複数アプリで利用)
・MC:アプリで使うモデルのクラス
・VC:アプリで使うビューのクラス
このような形でファイル名を付けると、ファイルの数が増えても大まかに分類できます。最初の2文字が大分類、その次の言葉が中分類、さらに次の言葉が小分類という形で、それぞれの役割が簡単に推測できてしまいます。非常に便利に使っているので、今のままの命名ルールで続けます。
今回の考察によって、ライブラリとアプリ独自のコードが、かなり区別できるようになるはずです。ライブラリ内の名前の変更が必要ですが、後になるほど大変なので、今やっておくしかないでしょう。少しずつ更新しようと思います。
もう1つ、作らなければならないものがあります。上記のルールを書いた書類を用意して、ライブラリを使っているアプリにも入れることです。そうしておくと、私以外の人がアプリをメンテするとき、ソースコードを解読しやすくなるでしょう。私が永遠にメンテできるはずはないので、次の人への準備は非常に重要だと思います。
アプリをビルドしたとき、余計な書類が含まれていてもアレなので、ルールを書いた書類はSwiftのソースコードが良いかもしれませんね。すべてをコメントとして書き、ファイル名にZZ_to_Developerとか付けて。メンテする人が、必ず見てくれるように。
さっそく、今作成中のライブラリから適用しています。これまでのライブラリやアプリも、バージョンアップの際に更新する予定です。