|
zip形式
tgz形式
オブジェクト指向についてはまだまだ勉強中ですが、「PHPでGoFのデザインパターンを実装したら、どんな感じになるんだろ?」と思ってしまったので、ちょっとずつやってみることにしました。
間違いやご意見がありましたら、遠慮なくツッコミを入れてくださいm(_"_)m
今回は、Adapterパターンで、「使い回しをするために一枚かぶせる」パターンです(以下のクラス図を参照)。
今回のサンプルは、すでに存在しているクラスを使い回す、というもので、上のクラス図との関係は、
- Target => NewApi
- Adapter => NewApiClass
- Adaptee => OldApiClass
となります。
ということで、以下がサンプルコードです。また、Abstractクラスなどを含めたスクリプトコードは、上のリンクからダウンロードできます。
今回のサンプルは、かなり単純なAPIの変換ですので、直接修正してしまっても大丈夫なように見えますが、複雑なクラスの場合、そう簡単にはいきませんよね。また、「修正する=テストが必要」ということで、不要なテスト工数を増やすことになってしまいます。Adapterパターンは、元となるクラスを全く修正することなく、目的のAPIに合わせる(変換する)ためのパターンと言えます。とはいえ、全く機能が異なるものには適応できません(当然ですが。。。)。
●Adapter.php
<?php
require_once("jp/ne/hi_ho/pat/dimension/Abstract.phl");
?>
<?php
class OldApiClass
{
var $str_;
function OldApiClass($str)
{
$this->str_ = $str;
}
function showNormal()
{
echo $this->str_ . "<br>";
}
function showBold()
{
echo "<b>" . $this->str_ . "</b><br>";
}
}
class NewApi
{
function printNormal() { Abstract::set("printNormal"); }
function printStrong() { Abstract::set("printStrong"); }
}
class NewApiClass extends NewApi
{
var $oldApiClass_;
function NewApiClass($str)
{
$this->oldApiClass_ = new OldApiClass($str);
}
function printNormal()
{
$this->oldApiClass_->showNormal();
}
function printStrong()
{
$this->oldApiClass_->showBold();
}
}
?>
<?php
echo "●古いAPI<br>";
$oldClass = new OldApiClass("ほげ");
$oldClass->showNormal();
$oldClass->showBold();
echo "●新しいAPI<br>";
$newClass = new NewApiClass("ほげ");
$newClass->printNormal();
$newClass->printStrong();
?>
●出力結果
●古いAPI
ほげ
ほげ(※Boldで表示されます)
●新しいAPI
ほげ
ほげ(※Boldで表示されます)
今回のサンプルでは、AdapterとAdapteeは「委譲」の関係ですが、継承を使ったものもあります。(以下のクラス図を参照)。
この場合、Adapterに相当するクラスがPHPの場合、どうしても多重継承となってしまうので、ちょっと無理そうです。。。
|