クラス設計の常識に反して、クラス名を動詞に、メソッド名を名詞にする
クラスを作るとき、ふつうはクラス名を名詞に、メソッド名を動詞にする。
class FileLoader { // クラス名は名詞
def load(name) { // メソッド名は動詞
...
}
}
しかし PHP のフレームワーク CodeIgniter では、一部のクラスでこれが逆になっている。つまり、クラス名が動詞で、メソッド名が名詞なのだ。
class Load {
function model($name) { ... }
function helper($name) { ... }
function library($name) { ... }
}
CodeIgniter では、このクラスのインスタンスが、クラス名と同じ名前で $this に設定される。そのため、実際使うときはこんな感じ。
$this->load->model('User'); // モデルをロード
$this->load->helper('Ajax'); // ヘルパーをロード
$this->load->library('Session'); // ライブラリをロードこうしてみると、英語として自然だ。少なくとも、$this->modelLoader->load('User') なんかよりはずっといい。
もちろん CodeIgniter 以外で使うなら、クラス名は名詞である必要はなく、インスタンスを入れる変数が名詞であればいいだけなんだが、それでもこの命名方法は面白い。
どんな場合にこの命名方法がハマるだろうかと考えたが、クラス名が「名詞+動詞+er」の形になっているときがそうなのかなと思う。
## 従来の命名方法
class MusicPlayer { # 名詞(Music) + 動詞(Play) + er
def play(...) { # 動詞
...
}
}
player = MusicPlayer()
player.play(...) # 主語.動詞(..目的語..)
## CodeIgniter 式の命名方法
class Play { # 動詞
def music() { # 名詞
...
}
}
play = MusicPlay.new(...)
play.music() # 動詞.目的語あれ、主語がないよ?
こうしてみると、今までの命名方法は「クラス名を名詞に、メソッド名を動詞に」していたわけじゃなくて、「クラス名を主語に、メソッド名を動詞に」していたわけか。
そして、CodeIgniter 方式は「クラス名を動詞に、メソッド名を名詞に」したわけじゃなくて、「クラス名を動詞に、メソッド名を目的語に」したといえる。
あと、この命名方法だと多態(polymorphism)は使えないな。結局は、普通の手続き型言語と変わらないことになりそう。
## 例えばこんなのは
class Player {
def play(); // abstract method
}
class MusicPlayer extends Player {
def play() { ... play music ... }
}
class GamePlayer extends Player {
def play() { ... play game ... }
}
## CodeIgnier 方式では使いにくい
class Play {
def music() { ... play music ... }
def game() { ... play game ... }
}
やっぱり、OOP言語で手続き型をしたいときにはハマりそう。でもそれって、設計が間違っていることなんじゃね?
うーむ。