最近気づいたのだが、自分はある意味において、軽度のstaticおじさんのようだ。
- クラスを書く。インスタンス変数やインスタンスメソッドを書く。
- privateなメソッドとして独立させたい処理が出てきたが、特にインスタンス変数を参照する必要がないので、クラスメソッドにする。
- privateなインスタンスメソッド、特にC++でいうconstメンバ関数を眺めていて、「あれ、この処理ってメソッド内で直接インスタンス変数を参照するのではなくて、これを呼び出す上位のメソッドにて引数で渡した方がよさそうだ」と感じたものを、privateなクラスメソッドにする。
- インスタンス変数は引数で渡す。
- privateなインスタンスメソッドを眺めていて、「あれ、この処理ってメソッド内で直接インスタンス変数を書き換えているけど、これを呼び出す上位のメソッドで書き換えた方がコードが読みやすくなるな」と感じたものを、privateなクラスメソッドにする。
- インスタンス変数に設定したい値は戻り値などで返す。
- privateなインスタンスメソッドを眺めていて、「あれ、この処理ってメソッド内で直接インスタンス変数を読み書きしてるけど、これを呼び出す上位のメソッドで読み書きした方が全体的にスッキリするな」と感じたものを、privateなクラスメソッドにする。
- 結果:インスタンスメソッドとクラスメソッドが出来上がるが、他人よりもクラスメソッドの占める割合が多い。
クラスメソッドの多くはprivateメソッドで、中身は枝葉の汎用的な処理が多い。これらのメソッドは、モジュール強度でいうデータ結合に該当する。グローバル変数やクラス変数はおろか、インスタンス変数すら直接参照していない。必要なものは引数で渡している。
キモは「言語仕様レベルでインスタンス変数を直接参照していないことを保証できる」という点だ。まあ、(使用している言語の仕様的に)グローバル変数やクラス変数は直接参照できてしまうのだが、そればインスタンスメソッドも同じだ。(グローバル変数やクラス変数の類も参照できないように選択できる仕様の言語とか、ないだろうか?)
データ結合のメソッドであるため、C++では静的メンバ関数だけでなくファイルスコープのstatic関数を用いることもある*1。Objective-Cでは、Objective-Cの形式のクラスメソッドではなく、ファイルスコープのstatic関数(C言語の形式の関数)をprivateなクラスメソッドの代用とすることが多い。
これはアレか、C言語が主戦場だから(関数分割的な発想に落ち着くの)か? それとも、普段私が扱っているクラスの粒度が全般的に大きいから(privateメソッドで処理を分割したくなるの)か? 両方かもしれない。
ちなみにクラス変数は基本的に使わない――あ、いや、定数扱いする場合はクラス変数にしていたか。シングルトンの実装でも使うな*2。
そんな訳で、既存のstaticおじさんから少しだけ進歩した次世代型staticおじさんを名乗ろうか検討中だ。関係ないけど、SubversionもGitも好きだがIDEはちょっと苦手*3だ。
*1:ソースファイルとヘッダファイルが分かれている場合に、ヘッダファイルに宣言を書く(==変更が発生する)のを避けるため。いや、個人的には静的メンバ関数にしても構わないのではないかと思うのだが……。
*2:シングルトンは扱いが難しいから、個人的には好みではないのだが。
*3:何しろVisual Studio使ったりXcode使ったりEclipse使ったりQt Creator使ったりvimとgdbを使ったりと、開発環境が頻繁に変わるものだから、なかなか覚えられない上に使わなくなって直ぐに忘れてしまう。その点、ソースコード管理はSubversionかGitが大半だから長く使うことが多いので、割と覚えてしまう。