PHPでオブジェクト指向を使うメリット

laravelで 会員登録完了メールを送る方法

こんにちはーむちょこです。
今日は、オブジェクト指向についてご紹介したいと思います!

オブジェクト指向って難しいイメージがあるかもしれませんが、フレームワークを作ったり使ったりしていると実は自然と身についているところもあると思います。
オブジェクト指向の便利な点を重点的に書いてみたので「これはいい!」と思ったところからぜひ使ってみてください:)

ちなみに車や動物は出てきません。

PHPとオブジェクト指向

PHPは元々、データとロジックが別々の「手続き型」が主流でした。

手続き型

時代の流れとともにアップデートを重ねながら、徐々にオブジェクト指向型に対応されていきましたが、未だに手続き型でも書けるようになっています。

そう、PHPってオブジェクト指向を知らなくても書けるのです。

それなのになぜ、みんなこぞってオブジェクト指向を使いたがるのか?
それは、オブジェクト指向型で書かれたコードは、手続き型に比べてコードの可読性と、変更に対する柔軟性が高いからです。

非常にシンプルなシステムであれば問題ありませんが、システムが複雑になればなるほど、手続き型で書かれたコードはスパゲッティコードと化し、バグの巣窟となりやすいです。

それを防ぐために、PHP、そしてPHPの数多くのフレームワークではオブジェクト指向が採用されています。

オブジェクトとは

オブジェクト指向に入る前に、それを構成する”オブジェクト”について少しお話させてください。

“オブジェクト”とは、データとロジックを1つにまとめたものです。

オブジェクト

人や言語によって解釈が分かれるところではありますが、PHPにおいては、クラス、クラスのインスタンス、インターフェースがオブジェクトであると私は解釈しています。

ヒント

オブジェクト指向に関するPHP公式マニュアルのページはこちら。

https://www.php.net/manual/ja/language.oop5.php

オブジェクトの例としてこのようなクラスを用意しました。

オブジェクトの例

DBに接続して、ユーザデータを取得するUserクラスです。

この後、オブジェクト指向の三原則に沿ってカスタマイズしていくのでぜひ変化を見ていってください:)

オブジェクト指向とは

オブジェクト指向とは、先ほどのオブジェクトを使ったプログラミングの技法です。

オブジェクト指向型

データとロジックがまとまっているだけでも少し見やすくなりましたが、 継承カプセル化ポリモーフィズムという3つの原則を使うとさらに便利になります。

継承

継承とは、親クラスのデータやロジックを子クラスが受け継ぐことです。

共通部分を親に定義することによって、何度も同じことを書かなくていい、つまり、修正のときも1箇所を直せばよく、見落としが予防できるというメリットがあります。

例えば、Userクラスと同様の性質を持ち、DBに接続してデータを取得する機能があるPostクラスが増えたとします。

Postクラス

$pdo, connect(), disconnect(), find()はUserクラスと全く同じなので、Modelクラスという親クラスを作ってそこにまとめることにします。

継承の例

Userクラス固有のfindByEmail()のみを残し、親クラスにあるものはすべて不要になりました。この後Commentクラスなどが出てきてもModelクラスを継承するだけですぐに作れそうです。
また、もしも接続方法に変更があった場合でもModelクラスのconnect()1箇所だけを変更すれば大丈夫になりました✨

注意点

共通の部分があるもの全てを継承させるのはアンチパターンです。

拡張するときに身動きがとれなくなってしまうことがあるので、同じような目的を持ち、同じような動作をするクラス同士かどうかを見極めつつ使いましょう。

カプセル化

カプセル化とは、情報の隠蔽です。
内部の仕組みを詳しく知らなくても安心して実行できるように、知らなくてもいいところは隠し、触れて良いところのみアクセス権を与えます。

今回の例では、 接続、切断を行うconnectメソッドとdisconncetメソッドはModelクラス内だけで行えるのでprivate、
接続情報の入っている$pdoは子クラスでも使いたいのでprotectedにしました。

カプセル化の例

こうすることで、親子以外が勝手に$pdoの情報を使ってDBを操作したり、重複して接続や切断をしてしまうのを防ぐことができます✨

ポリモーフィズム

ポリモーフィズムとは、多態性のことです。

複数のオブジェクトに同名の関数等を用意することで、オブジェクトの切り替えだけで違う処理を実現することができるようになります。

例として、指定したIDのUserデータやPostデータを出力するAPIを作るとします。
Modelクラスの子クラス達はfindメソッドを持つことが保証されているので、このように書くことができます。

ポリモーフィズムの例
public function show($model, $id)
{
    $data = $model->find($id);
    print_r($data);
}

引数の$modelにUserクラスのインスタンスを渡せばUserデータが、Postクラスのインスタンスを渡せばPostデータが表示されます。

この先Commentなどの新しいクラスができたときもshowメソッドの中身を変える必要はありませんし、
逆に全ての出力方法をjson形式に変えたいというときも1箇所を変えるだけで済みます✨

同じ関数名が存在していることが必須なので、インターフェースや継承と共に使われることが多い技法です。

まとめ
  • オブジェクト指向は、可読性と柔軟性に優れた技法です。
  • 継承は、子が親を受け継ぐことによって、共通の処理を一纏めにできます。
  • カプセル化は、不要な情報を隠すことによって、安全に拡張することができます。
  • ポリモーフィズムは、同名の関数等を用意することによって、処理の切り替えを簡単にできます。