第136回 PHPでダックタイピング

PHPでもクラスベースのオブジェクト指向が書けますね。
しかもPHPは動的型付けではなりませんか、ということは
とっても簡単にオブジェクト指向を使って強力なプログラミングが行なえます。

PHPポリモーフィズム

ポリモーフィズムは便利ですね。

すごく便利ですし、プログラムが超スマートになります。
プログラミングの発想も日本語で考えるような発想になって大変自然です。

しかもPHPならダックタイピングで書けます。


次のソースを見てください。

<?php

class Dog{ 
  function say(){ print 'わん' . "\n"; }
}

class Cat{
  function say(){ print 'にゃん' . "\n"; }
}

$animals = array(new Dog, new Cat);

foreach($animals as $animal){
  $animal->say();
}

?>

Dog(犬)クラスとCat(猫)クラスを作りました。
それぞれにsay()というメソッドを実行してもらいたいので、foreachを使いました。
このようにforeachで同じ処理を回すやりかたは大変便利です。
DogもCatも同じ処理をするということが一目でわかります。
参考:第68回 関数ではなくforで処理を共通化する - bingo_nakanishiの他言語出身者のためのPerl入門



では、このソースを実行してみましょう。
結果:

わん
にゃん

1回目のループで「わん」が表示され、
2回目のループで「にゃん」が表示されました。


1回目のループでは感覚的に

Dog->say()

2回目のループでは

Cat->say()

が実行されたイメージです。
これは arrayに入れた順番「array(new Dog, new Cat) 」通りですね。
1回目のループはDogのsay, 2回目のループはCatのsayと簡単に理解できます。



オブジェクト指向を使わない場合

オブジェクト指向を使わないで書いた場合、どのようになってしまうのでしょうか?
プログラムを学び始めてすぐにif文を習います。
if文を覚えただけで、結構バリエーションに富んだプログラムが書け、うれしくなります。
if文でプログラムを学ぶことを満足してしまうと次のようなソースを書いてしまうかもしれません。

<?php

$animals = array('Dog', 'Cat');

foreach($animals as $animal){
  if($animal == 'Dog'){
    print 'わん' . "\n";
  }else if($animal == 'Cat'){
    print 'にゃん' . "\n";
  } 
}

?>

if文で文字列'Dog'の場合なら「わん」
'Cat'の場合なら「にゃん」と表示するという処理になりました。



これがifの中でする事が多くなると、

  if($animal == 'Dog'){









  // 何百もあるソース









  }else if($animal == 'Cat'){

となって今どこのifの中を読んでいるのかパッと見ではわからなくなってしまいます。
そこで'Dog'だった場合に行なう処理を関数にしようとします。
そうするとifの中に書く量は減ります。

  if($animal == 'Dog'){
    dog();
  }else if($animal == 'Cat'){
    cat();
  } 

関数になったわけですが、オブジェクト指向の場合は初めからこの部分がメソッドです。
例:

$animal->do();


ここで、foreachの部分も含めて見比べてみましょう
オブジェクト指向

foreach($animals as $animal){
  $animal->do();
}


if文:

foreach($animals as $animal){
  if($animal == 'Dog'){
    print 'わん' . "\n";
  }else if($animal == 'Cat'){
    print 'にゃん' . "\n";
  } 
}

どちらが読みやすいでしょうか?


私はオブジェクト指向の方がごちゃごちゃしていなくてすっきりしているように感じます。



意味的な違い

プログラムの意味的な違いはどうでしょうか?

オブジェクト指向の方は、1回目のループで「Dogの処理が、2回目のループでCatの処理が行なわれる」とさっと読めますが、if文の方では、「CatでなくてDogの場合ならDogの処理、DogでなくてCatの場合ならCatの処理」というように「〜でなくて」という部分がどうも気になります。

もっとifのパターンが増えると、「〜でなくて〜でなくて〜でなくて〜でなくて」となって読むのが大変になってきます。「でなくて」の部分はプログラム的には「else」に当たる部分ですね。



まとめ

オブジェクト指向のパワーを知って、
うまく使うと激的にソースが変わり、書く為の思考回路、読む為の思考回路もごろっと変わります。


オブジェクト指向をうまくつかって設計ができるとかなり強力になります。
といってもこれがいつも簡単に思いついてサクっとコーディングできるのならば誰も設計で苦労はしなくなるのですが....
設計のひとつの手段としてオブジェクト指向だともっとうまく書けるかもという発想は大切だと思います。