【PHPデザインパターン】03_Adapter~APIを変更する
引用記事
この記事を書くきっかけになったブログです。
記事内の解説やソースコードは、こちらのブログと著者の公開リポジトリを参考にしています。
Do You PHP はてな〜[doyouphp][phpdp]PHPによるデザインパターン入門 - Adapter~APIを変更する
概要
- インターフェイスに互換性のないクラス同士を組み合わせることを目的とする。
- 既存のクラスに対して修正を加えることなく、他のインターフェイスへ変更する。
-
Targetクラス
を使用したいが、具体的な処理はAdapteeクラス
に任せたい。それを適合させるためにAdapterクラス
でインターフェイスを実装する。
- クライアント側からはインターフェイス(Adapterクラス)しか見えなくなり、その向こうにある処理の実装(TargetクラスとAdapteeクラス)を意識する必要がなくなる。
- パターンを再現する方法は、
継承
と委譲
の2種類がある。
- 既存のクラスを変更するのではなく、一枚皮をかぶせるようなクラスを作る。そのことから
Wrapperパターン
とも呼ばれる。
構成
処理の流れ
共通点
- クライアント側から
DisplaySourceFileインターフェイス
を利用してMyShowFileクラス
のメソッドを使用したい。
- そのアダプター(つなぎ役)として
DisplaySourceFileAdapterクラス
を作成する。
- DisplaySourceFileインターフェイスを定義し、DisplaySourceFileAdapterクラスに実装させる。
- DisplaySourceFileインターフェイスでは
displayメソッド
を定義している。(実装先のクラスではメソッドの実装が必須となる。)
- displayメソッドの具体的な実装は、MyShowFileクラスのメソッドを利用して行う。
継承
- DisplaySourceFileAdapterクラスが、MyShowFileクラスを継承する。
- コンストラクタで親クラス(MyShowFileクラス)のコンストラクタを呼び出し、親クラスにプロパティとして
$array
をセットする。
- 実装したdisplayメソッドから親クラス(MyShowFileクラス)のメソッドを呼び出す。セットした$arrayがその時に使用される。
委譲
- DisplaySourceFileAdapterクラス内で、MyShowFileクラスのインスタンスを作成する。
- コンストラクタでMyShowFileクラスのインスタンスを作成し、DisplaySourceFileAdapterクラスのプロパティとして
$array_obj
をセットする。同時に親クラスのプロパティとして$array
もセットされる。
- 実装したdisplayメソッドから、MyShowFileクラスのメソッドを呼び出す。セットした$arrayがその時に使用される。
ファイル構成
MyAdapter
├── Ext
│ ├── DisplaySourceFile.php
│ └── DisplaySourceFileAdapter.php
├── Impl
│ ├── DisplaySourceFile.php
│ └── DisplaySourceFileAdapter.php
├── MyShowFile.php
├── my_client_ext.php
└── my_client_lmpl.php
ソースコード
共通ファイル
MyShowFile.php
<?php
namespace DoYouPhp\PhpDesignPattern\Adapter\MyAdapter;
class MyShowFile
{
// プロパティを宣言する
private $array;
// コンストラクタ(オブジェクト生成時にコールされるメソッド)
// 配列でなければ例外を返す
public function __construct($array)
{
if (!is_array($array)) {
throw new \Exception('配列を渡してください');
}
$this->array = $array;
}
// 配列を改行で返す
public function BreakArray()
{
foreach ($this->array as $value) {
echo $value."<br>"."\n";
}
}
// 配列をタブ区切りで返す
public function TabArray()
{
foreach ($this->array as $value) {
echo $value."\t";
}
}
}
継承
my_client_ext.php
<?php
namespace DoYouPhp\PhpDesignPattern\Adapter\MyAdapter\Ext;
require dirname(dirname(__DIR__)).'/vendor/autoload.php';
use DoYouPhp\PhpDesignPattern\Adapter\MyAdapter\Ext\DisplaySourceFileAdapter;
$array = array('apple', 'orange', 'peach', 'banana');
try {
// DisplaySourceFileAdapterクラスをインスタンス化する
// コンストラクタで、親クラスであるMyShowFileクラスのコンストラクタを呼び出している
// 配列がMyShowFileクラスのプロパティである$arrayにセットされる
// 引数が配列でない場合は、例外を返す
// 引数を指定しない場合は、Fatal errorになる
$show_array = new DisplaySourceFileAdapter($array);
// 呼び出されているのはDisplaySourceFileインターフェイスのメソッド
// メソッド内で親クラスであるMyShowFileクラスのメソッドが呼び出され、$arrayが使用される
$show_array->display();
} catch (\Exception $e) {
echo $e->getMessage()."<br>"."\n";
}
Ext/DisplaySourceFile.php
<?php
namespace DoYouPhp\PhpDesignPattern\Adapter\MyAdapter\Ext;
// 実装先には、インターフェイスに含まれるメソッドを全て定義させる必要がある
// インターフェイス内でメソッドが実装されることはない
// メソッドは全てpublicである必要がある
interface DisplaySourceFile
{
public function display();
}
Ext/DisplaySourceFileAdapter.php
<?php
namespace DoYouPhp\PhpDesignPattern\Adapter\MyAdapter\Ext;
use DoYouPhp\PhpDesignPattern\Adapter\MyAdapter\Ext\DisplaySourceFile;
use DoYouPhp\PhpDesignPattern\Adapter\MyAdapter\MyShowFile;
// MyShowFileを継承し、DisplaySourceFileインターフェイスを実装する
class DisplaySourceFileAdapter extends MyShowFile implements DisplaySourceFile
{
// コンストラクタ(オブジェクト生成時にコールされるメソッド)
// 親クラスのコンストラクタは、サブクラスで自動的に呼び出されることはない
// そのため、parentキーワードでMyShowFileクラスのコンストラクタを呼び出している
public function __construct($array)
{
parent::__construct($array);
}
// インターフェイスに定義されたメソッド
// 親クラスであるMyShowFileクラスのメソッドを呼び出す
public function display()
{
parent::TabArray();
}
}
委譲
my_client_lmpl.php
<?php
namespace DoYouPhp\PhpDesignPattern\Adapter\MyAdapter\Impl;
require dirname(dirname(__DIR__)).'/vendor/autoload.php';
use DoYouPhp\PhpDesignPattern\Adapter\MyAdapter\Impl\DisplaySourceFileAdapter;
$array = array('apple', 'orange', 'peach', 'banana');
try {
// DisplaySourceFileAdapterクラスをインスタンス化する。
// コンストラクタでMyShowFileクラスのインスタンスが作成される
// 引数が配列でない場合は、例外を返す
// 引数を指定しない場合は、Fatal errorになる
$show_array = new DisplaySourceFileAdapter($array);
// 呼び出されているのはDisplaySourceFileインターフェイスのメソッド
// メソッド内でMyShowFileクラスのメソッドが呼び出されている
$show_array->display();
} catch (\Exception $e) {
echo $e->getMessage()."<br>"."\n";
}
Impl/DisplaySourceFile.php
<?php
namespace DoYouPhp\PhpDesignPattern\Adapter\MyAdapter\Impl;
// 実装先には、インターフェイスに含まれるメソッドを全て定義させる必要がある
// インターフェイス内でメソッドが実装されることはない
// メソッドは全てpublicである必要がある
interface DisplaySourceFile
{
public function display();
}
Impl/DisplaySourceFileAdapter.php
<?php
namespace DoYouPhp\PhpDesignPattern\Adapter\MyAdapter\Impl;
use DoYouPhp\PhpDesignPattern\Adapter\MyAdapter\Impl\DisplaySourceFile;
use DoYouPhp\PhpDesignPattern\Adapter\MyAdapter\MyShowFile;
// implements演算子で、DisplaySourceFileインターフェイスを実装する
// インターフェイスに定義されたメソッドは必ず実装する必要がある
class DisplaySourceFileAdapter implements DisplaySourceFile
{
// プロパティを宣言する
// MyShowFileクラスのインスタンスがセットされる
private $array_obj;
// コンストラクタ(オブジェクト生成時にコールされるメソッド)
// インポートしたMyShowFileクラスのインスタンスを作成する
public function __construct($array)
{
$this->array_obj = new MyShowFile($array);
}
// インターフェイスに定義されたメソッド
// 作成したMyShowFileクラスのインスタンスからメソッドを呼び出す
public function display()
{
$this->array_obj->TabArray();
}
}
Targetクラス
を使用したいが、具体的な処理はAdapteeクラス
に任せたい。それを適合させるためにAdapterクラス
でインターフェイスを実装する。継承
と委譲
の2種類がある。Wrapperパターン
とも呼ばれる。処理の流れ
共通点
- クライアント側から
DisplaySourceFileインターフェイス
を利用してMyShowFileクラス
のメソッドを使用したい。 - そのアダプター(つなぎ役)として
DisplaySourceFileAdapterクラス
を作成する。 - DisplaySourceFileインターフェイスを定義し、DisplaySourceFileAdapterクラスに実装させる。
- DisplaySourceFileインターフェイスでは
displayメソッド
を定義している。(実装先のクラスではメソッドの実装が必須となる。) - displayメソッドの具体的な実装は、MyShowFileクラスのメソッドを利用して行う。
継承
- DisplaySourceFileAdapterクラスが、MyShowFileクラスを継承する。
- コンストラクタで親クラス(MyShowFileクラス)のコンストラクタを呼び出し、親クラスにプロパティとして
$array
をセットする。 - 実装したdisplayメソッドから親クラス(MyShowFileクラス)のメソッドを呼び出す。セットした$arrayがその時に使用される。
委譲
- DisplaySourceFileAdapterクラス内で、MyShowFileクラスのインスタンスを作成する。
- コンストラクタでMyShowFileクラスのインスタンスを作成し、DisplaySourceFileAdapterクラスのプロパティとして
$array_obj
をセットする。同時に親クラスのプロパティとして$array
もセットされる。 - 実装したdisplayメソッドから、MyShowFileクラスのメソッドを呼び出す。セットした$arrayがその時に使用される。
ファイル構成
MyAdapter
├── Ext
│ ├── DisplaySourceFile.php
│ └── DisplaySourceFileAdapter.php
├── Impl
│ ├── DisplaySourceFile.php
│ └── DisplaySourceFileAdapter.php
├── MyShowFile.php
├── my_client_ext.php
└── my_client_lmpl.php
ソースコード
共通ファイル
MyShowFile.php
<?php
namespace DoYouPhp\PhpDesignPattern\Adapter\MyAdapter;
class MyShowFile
{
// プロパティを宣言する
private $array;
// コンストラクタ(オブジェクト生成時にコールされるメソッド)
// 配列でなければ例外を返す
public function __construct($array)
{
if (!is_array($array)) {
throw new \Exception('配列を渡してください');
}
$this->array = $array;
}
// 配列を改行で返す
public function BreakArray()
{
foreach ($this->array as $value) {
echo $value."<br>"."\n";
}
}
// 配列をタブ区切りで返す
public function TabArray()
{
foreach ($this->array as $value) {
echo $value."\t";
}
}
}
継承
my_client_ext.php
<?php
namespace DoYouPhp\PhpDesignPattern\Adapter\MyAdapter\Ext;
require dirname(dirname(__DIR__)).'/vendor/autoload.php';
use DoYouPhp\PhpDesignPattern\Adapter\MyAdapter\Ext\DisplaySourceFileAdapter;
$array = array('apple', 'orange', 'peach', 'banana');
try {
// DisplaySourceFileAdapterクラスをインスタンス化する
// コンストラクタで、親クラスであるMyShowFileクラスのコンストラクタを呼び出している
// 配列がMyShowFileクラスのプロパティである$arrayにセットされる
// 引数が配列でない場合は、例外を返す
// 引数を指定しない場合は、Fatal errorになる
$show_array = new DisplaySourceFileAdapter($array);
// 呼び出されているのはDisplaySourceFileインターフェイスのメソッド
// メソッド内で親クラスであるMyShowFileクラスのメソッドが呼び出され、$arrayが使用される
$show_array->display();
} catch (\Exception $e) {
echo $e->getMessage()."<br>"."\n";
}
Ext/DisplaySourceFile.php
<?php
namespace DoYouPhp\PhpDesignPattern\Adapter\MyAdapter\Ext;
// 実装先には、インターフェイスに含まれるメソッドを全て定義させる必要がある
// インターフェイス内でメソッドが実装されることはない
// メソッドは全てpublicである必要がある
interface DisplaySourceFile
{
public function display();
}
Ext/DisplaySourceFileAdapter.php
<?php
namespace DoYouPhp\PhpDesignPattern\Adapter\MyAdapter\Ext;
use DoYouPhp\PhpDesignPattern\Adapter\MyAdapter\Ext\DisplaySourceFile;
use DoYouPhp\PhpDesignPattern\Adapter\MyAdapter\MyShowFile;
// MyShowFileを継承し、DisplaySourceFileインターフェイスを実装する
class DisplaySourceFileAdapter extends MyShowFile implements DisplaySourceFile
{
// コンストラクタ(オブジェクト生成時にコールされるメソッド)
// 親クラスのコンストラクタは、サブクラスで自動的に呼び出されることはない
// そのため、parentキーワードでMyShowFileクラスのコンストラクタを呼び出している
public function __construct($array)
{
parent::__construct($array);
}
// インターフェイスに定義されたメソッド
// 親クラスであるMyShowFileクラスのメソッドを呼び出す
public function display()
{
parent::TabArray();
}
}
委譲
my_client_lmpl.php
<?php
namespace DoYouPhp\PhpDesignPattern\Adapter\MyAdapter\Impl;
require dirname(dirname(__DIR__)).'/vendor/autoload.php';
use DoYouPhp\PhpDesignPattern\Adapter\MyAdapter\Impl\DisplaySourceFileAdapter;
$array = array('apple', 'orange', 'peach', 'banana');
try {
// DisplaySourceFileAdapterクラスをインスタンス化する。
// コンストラクタでMyShowFileクラスのインスタンスが作成される
// 引数が配列でない場合は、例外を返す
// 引数を指定しない場合は、Fatal errorになる
$show_array = new DisplaySourceFileAdapter($array);
// 呼び出されているのはDisplaySourceFileインターフェイスのメソッド
// メソッド内でMyShowFileクラスのメソッドが呼び出されている
$show_array->display();
} catch (\Exception $e) {
echo $e->getMessage()."<br>"."\n";
}
Impl/DisplaySourceFile.php
<?php
namespace DoYouPhp\PhpDesignPattern\Adapter\MyAdapter\Impl;
// 実装先には、インターフェイスに含まれるメソッドを全て定義させる必要がある
// インターフェイス内でメソッドが実装されることはない
// メソッドは全てpublicである必要がある
interface DisplaySourceFile
{
public function display();
}
Impl/DisplaySourceFileAdapter.php
<?php
namespace DoYouPhp\PhpDesignPattern\Adapter\MyAdapter\Impl;
use DoYouPhp\PhpDesignPattern\Adapter\MyAdapter\Impl\DisplaySourceFile;
use DoYouPhp\PhpDesignPattern\Adapter\MyAdapter\MyShowFile;
// implements演算子で、DisplaySourceFileインターフェイスを実装する
// インターフェイスに定義されたメソッドは必ず実装する必要がある
class DisplaySourceFileAdapter implements DisplaySourceFile
{
// プロパティを宣言する
// MyShowFileクラスのインスタンスがセットされる
private $array_obj;
// コンストラクタ(オブジェクト生成時にコールされるメソッド)
// インポートしたMyShowFileクラスのインスタンスを作成する
public function __construct($array)
{
$this->array_obj = new MyShowFile($array);
}
// インターフェイスに定義されたメソッド
// 作成したMyShowFileクラスのインスタンスからメソッドを呼び出す
public function display()
{
$this->array_obj->TabArray();
}
}
Author And Source
この問題について(【PHPデザインパターン】03_Adapter~APIを変更する), 我々は、より多くの情報をここで見つけました https://qiita.com/yukibe/items/ad5966951fb92e274e57著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .