ホームページ >バックエンド開発 >PHPチュートリアル >PHPマスター|ファサードパターンで複雑さを管理します
<span><span><?php </span></span><span><span>public class User </span></span><span><span>{ </span></span><span> <span>public function borrowBook() { </span></span><span> <span>$bookManager = new Book_Manager(); </span></span><span> <span>$bookManager->returnBooks(); </span></span><span> </span><span> <span>$bookPayments = new Book_Payments(); </span></span><span> <span>if ($bookPayments->hasOverdueBooks()) { </span></span><span> <span>$bookPayments->payBookFines(); </span></span><span> <span>} </span></span><span> </span><span> <span>$bookLibrary = new Book_Library(); </span></span><span> <span>$bookReservations = new Book_Reservations(); </span></span><span> </span><span> <span>$book = $bookLibrary->searchBooks(); </span></span><span> <span>$isAvailable = $bookLibrary->isBookAvailable($book); </span></span><span> <span>$isReserved = $bookReservations->isBookReserved($book); </span></span><span> <span>if ($isAvailable && !isReserved) { </span></span><span> <span>$bookLibrary->locateBook($book); </span></span><span> </span><span> <span>$bookManager->borrowBook($book); </span></span><span> <span>$bookLibrary->updateBookAvailability($book, $status); </span></span><span> <span>} </span></span><span> <span>} </span></span><span><span>}</span></span>本を借りるプロセスは、実際には複雑なプロセスであることがわかります!この実装では、ユーザーは本を借りるために4つの異なるクラスと約10の方法と対話する必要があります。 機能の各ビットがアプリケーション内の個別の画面として実装されていると仮定します。このシステムで3冊の本を借りるために必要な努力を想像できますか?また、借り手は、予約のチェックやステータスの更新などの機能について知る必要はありません。確かに実装に問題があります。 ライブラリファサードの実装 ライブラリの複雑なワークフローからユーザーを切り離し、ユーザーに直接関連する情報のみを公開する単純化されたインターフェイスを可能にする必要があります。図書館のファサードの実装を見てみましょう。
<span><span><?php </span></span><span><span>class Library_Facade </span></span><span><span>{ </span></span><span> <span>public function returnBooks() { </span></span><span> <span>// previous implementation by calling necessary classes </span></span><span> <span>} </span></span><span> </span><span> <span>public function borrowBooks() { </span></span><span> <span>} </span></span><span> </span><span> <span>public function searchBooks() { </span></span><span> <span>} </span></span><span> </span><span> <span>public function reserveBooks() { </span></span><span> <span>} </span></span><span><span>}</span></span>ユーザーは、次の例に示すように、Library_Facadeクラスのbrobrebook()メソッドに電話することで本を借りることができます。
<span><span><?php </span></span><span><span>class User </span></span><span><span>{ </span></span><span> <span>public function borrowBook() { </span></span><span> <span>$libraryFacade = new Library_Facade(); </span></span><span> <span>$libraryFacade->borrowBook(); </span></span><span> <span>} </span></span><span><span>}</span></span>このファサードベースの実装により、ユーザーはLibrary_facadeクラスとのみ話し合い、それ以外の機能がどのように実装されているかわかりません。ユーザーはファサードから任意の機能を直接リクエストでき、ファサードは複雑なプロセスを処理し、適切な情報を返す責任があります。ファサードパターンは、各ユニットが他のユニットに関する知識を最小限に抑える必要があるという最小の知識の原則に準拠しています。 低レベルの機能はファサードを介してユーザーから隠されていますが、ユーザーは必要に応じて低レベルのクラスを直接要求できます。自分のプロジェクトと、それを実現せずにファサードパターンを実装した状況を見つける可能性のある場所について考えてください。
ファサードは、クラスライブラリなど、より大きなコードボディに単純化されたインターフェイスを提供するオブジェクトです。ファサードは:
- ファサードには一般的なタスクの便利な方法があるため、ソフトウェアライブラリを使いやすく、理解し、テストしやすいものにします。 同じ理由で、ライブラリをより読みやすくします;
ほとんどのコードはファサードを使用してシステムの開発においてより柔軟性を可能にするため、- 外部コードの依存関係を削減します。
は、十分に設計されたAPIのコレクションを1つの適切に設計したAPIで包みます。 ファサードパターンの定義に記載されているコンポーネントを識別するライブラリの例のクラス図を次に示します。Real Worldの実装
前のセクションでは、ライブラリシステムを例として使用して、ファサードパターンの背後にある理論を学びました。現実の世界では、ファサードは、ライブラリシナリオの実装よりもはるかに複雑になる可能性があります。実際のアプリケーションとライブラリのコンテキストで、パターンのいくつかの実装を確認しましょう。 オープン認証のためのOpauth
私は最近、Opauthという人気のあるオープン認証ライブラリに関する記事を書きました。まだお届けしない場合は、読むことをお勧めします。プロのソーシャルネットワークサイトを開発したと仮定し、ユーザーがTwitter、LinkedIn、Facebookなどの他の人気のあるサイトを使用して認証できると仮定します。認証プロセスを完了するために、既存のサードパーティライブラリを使用して、ネットワークのサービスにアクセスします。目的の機能を達成するためのTwitterライブラリを使用して、いくつかのサンプルコードを見てみましょう。<span><span><?php </span></span><span><span>public class User </span></span><span><span>{ </span></span><span> <span>public function borrowBook() { </span></span><span> <span>$bookManager = new Book_Manager(); </span></span><span> <span>$bookManager->returnBooks(); </span></span><span> </span><span> <span>$bookPayments = new Book_Payments(); </span></span><span> <span>if ($bookPayments->hasOverdueBooks()) { </span></span><span> <span>$bookPayments->payBookFines(); </span></span><span> <span>} </span></span><span> </span><span> <span>$bookLibrary = new Book_Library(); </span></span><span> <span>$bookReservations = new Book_Reservations(); </span></span><span> </span><span> <span>$book = $bookLibrary->searchBooks(); </span></span><span> <span>$isAvailable = $bookLibrary->isBookAvailable($book); </span></span><span> <span>$isReserved = $bookReservations->isBookReserved($book); </span></span><span> <span>if ($isAvailable && !isReserved) { </span></span><span> <span>$bookLibrary->locateBook($book); </span></span><span> </span><span> <span>$bookManager->borrowBook($book); </span></span><span> <span>$bookLibrary->updateBookAvailability($book, $status); </span></span><span> <span>} </span></span><span> <span>} </span></span><span><span>}</span></span>ご覧のとおり、Twitter固有のライブラリメソッドのセットを呼び出して、目的の機能を実装します。 LinkedInとFacebookの両方に同様のアプローチが必要です。プロセスはすでに複雑になっています。 Twitter、Facebook、またはLinkedInアプリケーションを開発していません。資格情報を検証し、ユーザーを認証するだけです。当社のアプリケーションは、これらの各サービスの実装について心配するべきではありません。 Opauthライブラリをファサードインターフェイスとして使用することにより、この問題を解決できます。まず、Opauthプラグインによって識別される共通形式で目的のサービスのログインURLを指定する必要があります。認証プロセスを実装するための次のコードを検討してください。<span><span><?php </span></span><span><span>class Library_Facade </span></span><span><span>{ </span></span><span> <span>public function returnBooks() { </span></span><span> <span>// previous implementation by calling necessary classes </span></span><span> <span>} </span></span><span> </span><span> <span>public function borrowBooks() { </span></span><span> <span>} </span></span><span> </span><span> <span>public function searchBooks() { </span></span><span> <span>} </span></span><span> </span><span> <span>public function reserveBooks() { </span></span><span> <span>} </span></span><span><span>}</span></span>ログインリンクが要求されると、OpauthはURLから要求されたサービスを識別し、ライブラリを初期化してユーザーを認証にリダイレクトします。アプリケーションは、ログインリンクを作成し、初期化メソッドを呼び出すだけで必要です。すべての複雑な認証のものは、各サービスのそれぞれのライブラリを使用して、舞台裏で処理されます。これは、ファサードパターンを効果的に使用するための完璧な例と見なすことができます。WordPress Meta関数
WordPressは、コードの品質を考慮して、真剣なPHP開発者の中で最も人気のあるフレームワークの1つではありません。ただし、WordPressコードベース内で、多くの成功したファサードの実装を簡単に見つけることができます。ここでは、WordPress投稿のカスタムデータを保存するためのupdate_post_meta()関数を見てみましょう。 WordPressを使用すると、既存の投稿に関連付けられたカスタムフィールドを作成できます。これらのフィールドを通常の状況でどのように保存するかを考えてください。次のすべてのタスクを実装する必要があります。これは、1つのカスタムフィールドを保存するための非常に多くの作業です! WordPressは、update_post_meta()と呼ばれる組み込み関数を提供することにより、これらのフィールドを保存する複雑さを隠します ファサードとして行動する。これにより、アプリケーションに関連する必要なデータを渡すことに集中することができます。前述のタスクはすべてユーザーから隠されています。 ここで、update_post_meta()の実装を検討して、その機能をファサードとして識別します。
- フィールドデータを検証します
- HTMLタグ、スクリプト、およびSQLインジェクションのデータをフィルタリング
- データベースのフィールドの存在を確認してください
- 存在ステータスに基づいてレコードを保存または更新
<span><span><?php </span></span><span><span>public class User </span></span><span><span>{ </span></span><span> <span>public function borrowBook() { </span></span><span> <span>$bookManager = new Book_Manager(); </span></span><span> <span>$bookManager->returnBooks(); </span></span><span> </span><span> <span>$bookPayments = new Book_Payments(); </span></span><span> <span>if ($bookPayments->hasOverdueBooks()) { </span></span><span> <span>$bookPayments->payBookFines(); </span></span><span> <span>} </span></span><span> </span><span> <span>$bookLibrary = new Book_Library(); </span></span><span> <span>$bookReservations = new Book_Reservations(); </span></span><span> </span><span> <span>$book = $bookLibrary->searchBooks(); </span></span><span> <span>$isAvailable = $bookLibrary->isBookAvailable($book); </span></span><span> <span>$isReserved = $bookReservations->isBookReserved($book); </span></span><span> <span>if ($isAvailable && !isReserved) { </span></span><span> <span>$bookLibrary->locateBook($book); </span></span><span> </span><span> <span>$bookManager->borrowBook($book); </span></span><span> <span>$bookLibrary->updateBookAvailability($book, $status); </span></span><span> <span>} </span></span><span> <span>} </span></span><span><span>}</span></span>必要なコードのみが表示されます。 update_metadata()関数の完全なソースコードは、wp-includesディレクトリ内のmeta.phpファイルで使用できます。ただし、ここではすべての検証、フィルタリング、およびデータベースの更新が実装されていることを確認でき、ファサードインターフェイスのみが詳細について知識を持っています。結論
ファサードは、ソフトウェア開発で最もシンプルで使いやすいデザインパターンの1つです。この記事を通して、ファサードパターンのさまざまな実装について説明しました。さあ、以下のコメントであなたの経験を共有しましょう。ファサードを利用するライブラリやサービスを知っていますか?出会ったファサードパターンの実用的な実装を自由に共有してください。 Fotoliaを介した画像 ファサードパターンに関するよくある質問ソフトウェアデザインのファサードパターンの主な目的は何ですか?ファサードパターンは、クラス、ライブラリ、またはフレームワークの複雑なシステムに単純化されたインターフェイスを提供する構造設計パターンです。システムの複雑さを隠し、クライアントがシステムにアクセスできるクライアントにインターフェイスを提供します。このパターンには、クライアントが必要とする単純化された方法を提供し、既存のシステムクラスのメソッドに呼び出しを委任する単一のクラスが含まれます。ファサードパターンはコードの読みやすさと使いやすさをどのように改善しますか?複雑なサブシステムにシンプルなインターフェイスを提供することにより、コードの読みや使用性を向上させます。クライアントにいくつかのサブシステムクラスを直接処理させる代わりに、ファサードは統一されたインターフェイスを使用してサブシステムをカプセル化します。これにより、サブシステムを理解するために必要な学習曲線が削減され、サブシステムの使用と管理が容易になります。ファサードパターンは、コンピューターの使用です。コンピューターをオンにすると、内部コンポーネントがどのように連携してシステムを起動する方法を理解する必要はありません。電源ボタン(ファサード)を押すだけで、複雑なプロセスが舞台裏で行われます。
ファサードパターンを使用することの利点と欠点は何ですか?
ファサードパターンの主な利点は、複雑なサブシステムへのインターフェイスを単純化し、クライアントが使いやすくすることです。また、サブシステムとそのクライアント間のデカップリングを促進し、システムをよりモジュール化し、維持しやすくすることができます。ただし、潜在的な不利な点は、ファサードにあまりにも多くの機能が置かれている場合、ファサードパターンがボトルネックになる可能性があることです。また、クライアントからサブシステムの有用な機能を非表示にすることができます。
ファサードパターンは、他の構造設計パターンとどのように異なりますか?個々のオブジェクトの動作を追加または変更するために使用されます。ファサードパターンは、複雑なクラスシステムを簡素化するために使用されます。クライアントからサブシステムの複雑さを隠している複雑なサブシステムへの単純化されたインターフェイスを提供します。他のデザインパターンと組み合わせて使用されます。たとえば、シングルトンパターンで使用して、ファサードの1つのインスタンスのみが作成されるようにすることができます。また、抽象的な工場パターンで使用して、関連するオブジェクトのファミリを作成するための単純なインターフェイスを提供することもできます。オブジェクト間の通信を制限することにより、最小の知識(またはデメテルの法則)の原則に貢献します。クライアントは、サブシステムのクラスではなく、ファサードと通信する必要があります。これにより、オブジェクト間の依存関係が削減され、システムがより堅牢で維持が容易になります。マルチスレッドアプリケーション。ただし、ファサードがスレッドセーフであることを確認するために注意する必要があります。これは、人種条件を防ぐためにロックやセマフォなどの同期メカニズムを使用することで実現できます。
ファサードパターンはパフォーマンスにどのように影響しますか?クライアントは対話する必要があります。これにより、オブジェクトの作成とメソッドの呼び出しのオーバーヘッドが減少します。ただし、ファサードがボトルネックになった場合、パフォーマンスに悪影響を与える可能性があります。複雑なサブシステムに簡素化されたインターフェイスを提供するファサードクラス。ファサードクラスは、サブシステムをカプセル化し、コールをサブシステムクラスに委任する必要があります。クライアントは、サブシステムクラスと直接ではなく、ファサードを介してサブシステムと対話する必要があります。
以上がPHPマスター|ファサードパターンで複雑さを管理しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。