PHP
デザインパターン
インピーダンスミスマッチ
ポリモーフィズム
NucoDay 6

ファクトリーを使ってインピーダンスミスマッチを解消し、ポリモーフィズムを実現する

More than 1 year has passed since last update.

Nuco Advent Calendar 6日目の記事です。

はじめに

タイトルを読んでイメージが出来る方にはあまり面白みがないかもしれないです。。

インピーダンスミスマッチ?

分からない♪(ぱんぱん)、分からない♪(ぱんぱん)、分からないなら帰ってウィキペディア!!

ということでウィキペディアから拝借

オブジェクト指向プログラミングとリレーショナルデータベースは異なるデータモデルを持つ。
リレーショナルデータベースの関係モデルは整合性を重視した2次元表の構造を持っており、データ同士は関係(リレーション)によって表現される。
一方オブジェクト指向プログラミングのデータはひとまとまりのオブジェクトとして扱われ、関係モデルにおける関係と同じような構造を持つとすれば、オブジェクト指向としての恩恵が得られるモデル設計ができない。
逆も然り、オブジェクトモデルをリレーショナルデータベースで実現しようとすると、整合性が損なわれたり、関係が表現できなくなる。
このデータ構造や概念の隔たりがインピーダンスミスマッチと呼ばれる。

ポリモーフィズム?

分からない♪(ぱんぱん)、分か

プログラミング言語の型システムの性質を表すもので、プログラミング言語の各要素(定数、変数、式、オブジェクト、関数、メソッドなど)についてそれらが複数の型に属することを許すという性質を指す。
ポリモルフィズム、多態性、多相性、多様性とも呼ばれる。

いや、ちょっと何言ってるかよく分からな・・・

ポイントは、
共通のメソッドを呼んだ際に、オブジェクトによってその機能を変えられる
ことじゃないでしょうか。

例:複数の権限があるECサービスの場合

ECサイトのユーザー権限として以下の4つがあったとします。

  • タイプ1:閲覧のみ可能
  • タイプ2:閲覧、販売、購入が可能
  • タイプ3:閲覧、販売が可能
  • タイプ4:閲覧、購入が可能

ポリモーフィズムを使わない場合

ユーザーの権限をセッション等で管理していた場合、以下のようになるのではないでしょうか。
NG.png

この場合、権限が増える度にcase文を増やすことになります。
また、他の処理でもif-elseやswitchが乱立することになり、色々面倒です。

ポリモーフィズムを適用した場合

OK.png

この場合、アカウントの権限が増えてもメソッドの処理を変更する必要がありません。

どうなってるの?

ソースコードはこちら

※ControllerとModelしか置いてないですが、Repository以外はPOPOで書いてます
※フレームワークはcodeigniterです

想定してるDBはこんな感じです

user_id type name password
001 1 田中 #hs465_dd
002 2 山田 fff5_lkj
003 3 内山 gs323_jlg
004 4 佐藤 eeeelkj

そして、typeごとに以下のようなクラスを作ります。
(今回はAccount1~Account4まで作りました)

OK2.png

OK2.png

12行目の$userには、$userIdに対応する権限のオブジェクトが入ります。

田中さんの場合

AccountRepositoryのfindメソッドが呼ばれます。
OK3.png

user_idが001と一致するため、AccountFactoryのcreateメソッドが呼ばれます。
OK4.png

typeが1なので、$userには Account1オブジェクトが入ります。

タイプ1の権限の場合、閲覧のみなので、Account1オブジェクトを参照する$userがbuyメソッドを呼び出すとNotAuthorizedExceptionが呼ばれます。

buyメソッドの中身は書いてないですが、タイプ2の山田さんの場合は例外処理にならず、「何か買う」が表示されます。

まとめ

共通のメソッドを呼んだ際に、オブジェクトによってその機能を変えられる
本記事とソースコードが、ポリモーフィズムを理解する手助けになれば幸いです。