クラス設計の常識に反して、クラス名を動詞に、メソッド名を名詞にする
クラスを作るとき、ふつうはクラス名を名詞に、メソッド名を動詞にする。
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言語で手続き型をしたいときにはハマりそう。でもそれって、設計が間違っていることなんじゃね?
うーむ。