インターフェイスベースのプログラミング
PHP プログラマーとして、インターフェイスに基づいてプログラミングする方法を学ぶことで私の人生は変わり、サードパーティの PHP コンポーネントを統合することでプロジェクトを改善する能力が大幅に向上しました。インターフェイスは新しい機能ではありませんが、日常の作業で理解し、使用する必要がある重要な機能です。
それでは、PHP のインターフェースとは一体何でしょうか?インターフェイスは 2 つの PHP オブジェクト間の契約です。あるオブジェクトが別のオブジェクトを呼び出すとき、相手が何であるかを知る必要はなく、相手が何ができるかを知るだけで済みます。インターフェイスを使用すると、コードの依存関係の結合が軽減され、コードから目的のインターフェイスを実装するサードパーティ コードを呼び出すことができるようになります。サードパーティのコードがインターフェイスを実装しているかどうかだけを気にする必要があり、サードパーティのコードがこれらのインターフェイスをどのように実装しているかについてはまったく気にする必要はありません。実際の例を見てみましょう。
Sunshine PHP Developer Conference に出席するためにフロリダ州マイアミに行くとします。市内を探索したかったので、地元のレンタカー会社に直行しました。彼らは現代のコンパクトカー、スバルステーションワゴン、ブガッティヴェイロンを持っていました(驚いたことに)。私は街を移動するために何らかの交通手段が必要だと思っていました。これら 3 台の乗り物はすべて私のニーズに適合します。しかし、それぞれの車はまったく異なります。ヒュンダイアクセントも悪くありませんが、私はもう少しダイナミックなものが好きです。私には子供がいないので、ステーションワゴンはまだ少し大きいです。じゃあ、ブガッティを選んでください。
実際には、これら 3 台の車はすべて共通の既知のインターフェースを共有しているため、私はどの車でも運転することができます。すべての車にはハンドル、アクセル ペダル、ブレーキ ペダル、方向指示器があり、すべての車が燃料としてガソリンを使用します。しかし、ブガッティのパワーは私には手に負えないほど強力ですが、現代の車のドライビングインターフェイスはまったく同じです。 3 台の車はすべて同じ既知のインターフェイスを共有しているため、より好きなモデルを選択する機会があります (正直に言うと、最終的にはおそらくヒュンダイを選択するでしょう)。
PHP のオブジェクト指向の側面にも同じ概念が存在します。コードで特定のクラスのオブジェクト (特定の実装を表す) を使用する場合、そのクラスのオブジェクトしか永久に使用できないため、コードの機能は非常に制限されます。ただし、コードでインターフェイスを使用する場合、コードはインターフェイスを実装するオブジェクトの使用方法をすぐに認識します。私のコードでは、インターフェイスがどのように実装されるかはまったく考慮されません。私のコードでは、オブジェクトがインターフェイスを実装するかどうかのみが考慮されます。すべてを説明するために例を使用します。
さまざまなデータ ソースからデータを取得し、ドキュメント ストリームからデータを読み取り、ターミナル コマンドを取得できる DocumentStore という名前の PHP クラスがあるとします。 DocumentStore インスタンスに保存された各ドキュメントには一意の ID があります。例 2-6 は、DocumentStore クラスを示しています。
例 2-6 DocumentStore クラスの定義
class DocumentStore { protected $data = []; public function addDocument(Documentable $document) { $key = $document->getId(); $value = $document->getContent(); $this->data[$key] = $value; } public function getDocuments() { return $this->data; } }
例 2-7 Documentable インターフェースの定義
interface Documentable { public function getId(); public function getContent(); }
それで、これを行うメリットは何ですか?利点は、異なる機能を持つ複数のドキュメント取得クラスを構築できることです。例 2-8 は、curl を介してリモート アドレスから HTML を取得するインターフェイス実装を示しています。
例 2-8 HtmlDocument クラスの定義
<?php class HtmlDocument implements Documentable { protected $url; public function __construct($url) { $this->url = $url; } public function getId() { return $this->url; } public function getContent() { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $this->url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_MAXREDIRS, 3); $html = curl_exec($ch); curl_close($ch); return $html; } }
例2-9 StreamDocumentクラスの定義
<?php class StreamDocument implements Documentable { protected $resource; protected $buffer; public function __construct($resource, $buffer = 4096) { $this->resource = $resource; $this->buffer = $buffer; } public function getId() { return 'resource-' . (int)$this->resource; } public function getContent() { $streamContent = ''; rewind($this->resource); while (feof($this->resource) === false) { $streamContent .= fread($this->resource, $this->buffer); } return $streamContent; } }
例2-10 CommandOutputDocumentクラスの定義
<?php class CommandOutputDocument implements Documentable { protected $command; public function __construct($command) { $this->command = $command; } public function getId() { return $this->command; } public function getContent() { return shell_exec($this->command); } }
例 2-11 DocumentStore
<?php $documentStore = new DocumentStore(); // Add HTML document $htmlDoc = new HtmlDocument('http://php.net'); $documentStore->addDocument($htmlDoc); // Add stream document $streamDoc = new StreamDocument(fopen('stream.txt', 'rb')); $documentStore->addDocument($streamDoc); // Add terminal command document $cmdDoc = new CommandOutputDocument('cat /etc/hosts'); $documentStore->addDocument($cmdDoc); print_r($documentStore->getDocuments());
今日、プログラミングインターフェイスはより柔軟なコードを作成し、私たちは特定の実装を気にすることなく、これらのタスクを他の人に任せています。ますます多くの人 (同僚、オープンソース プロジェクトのユーザー、会ったことのない開発者など) が、Just インターフェイスを理解するだけで、あなたとシームレスに動作するコードを作成できます。
以上、[最新の PHP] 第 2 章 新機能 2 インターフェイスベースのプログラミングについて内容を含めて紹介しましたが、PHP チュートリアルに興味のある友人の参考になれば幸いです。