目次
ファサードという言葉は、もともと建築の表面や外観を指しますが、国内ではファサードという言葉に注目する方が多いかもしれません。 Laravel の人気について、誰もが満場一致で Laravel のファサードを「ファサード」と訳しているようです。正直、翻訳資料で初めて「ファサード」という言葉が出てきたのを見たとき、あなたも私と同じように思ったと思います。 「今まで、中国語でファサードと言わなければならない場合、「ファサード」という言葉を使わなければならない場合、私の心はまだ意識的に「カチッ」とせず、ここに問題があることはわかっています。
设计模式似曾相识?" >感觉facade pattern与其他的设计模式似曾相识?
ホームページ バックエンド開発 PHPチュートリアル PHPでのファサードパターンの使い方の詳細な説明

PHPでのファサードパターンの使い方の詳細な説明

May 19, 2018 am 10:35 AM
facade pattern php

今回は、PHP での ファサード パターンの使用方法について詳しく説明します。PHP でファサード パターンを使用する際の 注意事項 は何ですか?以下は実際的なケースです。 ファサードという言葉の翻訳について

ファサードという言葉は、もともと建築の表面や外観を指しますが、国内ではファサードという言葉に注目する方が多いかもしれません。 Laravel の人気について、誰もが満場一致で Laravel のファサードを「ファサード」と訳しているようです。正直、翻訳資料で初めて「ファサード」という言葉が出てきたのを見たとき、あなたも私と同じように思ったと思います。 「今まで、中国語でファサードと言わなければならない場合、「ファサード」という言葉を使わなければならない場合、私の心はまだ意識的に「カチッ」とせず、ここに問題があることはわかっています。

ファサードの最も適切な翻訳は何ですか?しかし、単に翻訳をせず、英語の単語に遭遇したときにそのまま使用することを主張する人もいます。結局のところ、これは初心者が理解できるようにするためのものではありません。その後、台湾の学者、正確には台湾のウィキペディアがファサードパターンを「外観パターン」と訳しているのを偶然目にし、このパターンの実際の役割を考えると、すぐに安心しました。 laravelのファサードは厳密にはファサードパターンではありませんが、ファサードという言葉の誤用と誤解を招くとして多くの人がまだlaravelを批判していますが、依然としてファサードパターンを借用または模倣しているため、laravelのファサード、この記事も同様です。もちろん「外観」と訳した方が分かりやすいと思いますが、「サービス外観」でも構いません。それでも、個人的な観点からは、むしろ「サービスロケーター」、「サービスエージェント」、または「サービスエイリアス」と呼びたいと思っています。実際、海外でもこのように名前を変更することを提案する人がたくさんいますが、この問題に対するテイラーの態度は異常です。硬いので今のところ無理にやる必要はありません。

以下を通して、ファサードパターンとは何かを実際に理解した後、なぜそれが「ファサードパターン」とより適切に翻訳されるのかがよりよく理解できると思います。

ファサードパターン(「外観パターン」の定義)とは

現実世界でも

プログラミング

の世界でも、ファサード(外観)の目的は、本来あるかもしれないものを「覆う」ことです。中国のことわざで、美しく魅力的な外見、または仮面。外見とは何ですか? 「人は着るものに依存し、馬は鞍に依存する。」これに基づいて、ファサード パターンは、1 つ以上の乱雑で複雑でリファクタリングが難しいクラスを、美しくエレガントなインターフェイス (インターフェイス) に追加 (または変換) することで、より幸せで快適になれるようにするものです。それを操作するのに便利であり、それによってその背後にある実際のロジックを間接的に操作します。

ファサード パターンを使用する場合

ファサード パターン (「外観パターン」) は、1 つ以上のサブシステムに統合されたエントリ インターフェイス (インターフェイス) または操作インターフェイスを提供するためによく使用されます。

他人が残したプロジェクトやサードパーティのコードを操作する必要がある場合。特に一般に、これらのコードは簡単にリファクタリングされず、テストも提供されません。この時点で、元のコードを「ラップ」するファサード (「外観」) を作成して、使用シナリオを簡素化または最適化できます。


いくら言っても、より直感的に理解できるようにいくつかの例を挙げてみましょう:

例 1: Java では、コンピューター内の複雑なシステム情報はファサードを通じて操作されます

このような複雑なサブシステム ロジックがあると仮定します。 :

class CPU {
 public void freeze() { ... }
 public void jump(long position) { ... }
 public void execute() { ... }
}
class Memory {
 public void load(long position, byte[] data) {
  ...
 }
}
class HardDrive {
 public byte[] read(long lba, int size) {
  ...
 }
}
ログイン後にコピー

それらをより便利に操作するために、ファサードを作成できます:

class Computer {
 public void startComputer() {
  cpu.freeze();
  memory.load(BOOT_ADDRESS, hardDrive.read(BOOT_SECTOR, SECTOR_SIZE));
  cpu.jump(BOOT_ADDRESS);
  cpu.execute();
 }
}
ログイン後にコピー

その後、顧客は次のように簡単にそれを呼び出すことができます:

class You {
 public static void main(String[] args) {
  Computer facade = new Computer();
  facade.startComputer();
 }
}
ログイン後にコピー

例 2: 悪いサードパーティの電子メール クラス

次のように仮定します。特に、その中のすべてのメソッド名を理解するには数秒間一時停止する必要があるため、次のサードパーティの電子メール クラスを使用する必要があります。

interface SendMailInterface
{
 public function setSendToEmailAddress($emailAddress);
 public function setSubjectName($subject);
 public function setTheEmailContents($body);
 public function setTheHeaders($headers);
 public function getTheHeaders();
 public function getTheHeadersText();
 public function sendTheEmailNow();
}
class SendMail implements SendMailInterface
{
 public $to, $subject, $body;
 public $headers = array();
 
 public function setSendToEmailAddress($emailAddress)
 {
  $this->to = $emailAddress;
 }
 public function setSubjectName($subject)
 {
  $this->subject = $subject;
 }
 public function setTheEmailContents($body)
 {
  $this->body = $body;
 }
 public function setTheHeaders($headers)
 {
  $this->headers = $headers;
 }
 public function getTheHeaders()
 {
  return $this->headers;
 }
 public function getTheHeadersText()
 {
  $headers = "";
  foreach ($this->getTheHeaders() as $header) {
   $headers .= $header . "\r\n";
  }
 }
 
 public function sendTheEmailNow()
 {
  mail($this->to, $this->subject, $this->body, $this->getTheHeadersText());
 }
}
ログイン後にコピー

現時点では、ソース コードを直接変更することはできません。 、ファサードを作成しましょう

class SendMailFacade
{
 private $sendMail;
 public function construct(SendMailInterface $sendMail)
 {
  $this->sendMail = $sendMail;
 }
 public function setTo($to)
 {
  $this->sendMail->setSendToEmailAddress($to);
  return $this;
 }
 public function setSubject($subject)
 {
  $this->sendMail->setSubjectName($subject);
  return $this;
 }
 public function setBody($body)
 {
  $this->sendMail->setTheEmailContents($body);
  return $this;
 }
 public function setHeaders($headers)
 {
  $this->sendMail->setTheHeaders($headers);
  return $this;
 }
 public function send()
 {
  $this->sendMail->sendTheEmailNow();
 }
}
ログイン後にコピー

次に、最適化なしの元の端末呼び出しは次のようになります:

$sendMail = new SendMail();
$sendMail->setSendToEmailAddress($to);
$sendMail->setSubjectName($subject);
$sendMail->setTheEmailContents($body);
$sendMail->setTheHeaders($headers);
$sendMail->sendTheEmailNow();
ログイン後にコピー

外観クラスを使用すると、次のようになります:

$sendMail  = new SendMail();
$sendMailFacade = new sendMailFacade($sendMail);
$sendMailFacade->setTo($to)->setSubject($subject)->setBody($body)->setHeaders($headers)->send();
ログイン後にコピー

例 3: 商品トランザクションのプロセスを完了する複雑さ

商品取引には次の手順が必要であると仮定します。

$productID = $_GET['productId']; 
$qtyCheck = new productQty();
 // 检查库存
if($qtyCheck->checkQty($productID) > 0) {
  
 // 添加商品到购物车
 $addToCart = new addToCart($productID);
  
 // 计算运费
 $shipping = new shippingCharge();
 $shipping->updateCharge();
  
 // 计算打折
 $discount = new discount();
 $discount->applyDiscount();
  
 $order = new order();
 $order->generateOrder();
}
ログイン後にコピー

可以看到,一个流程呢包含了很多步骤,涉及到了很多Object,一旦类似环节要用在多个地方,可能就会导致问题,所以可以先创建一个外观类:

class productOrderFacade {
 public $productID = '';  
 public function construct($pID) {
  $this->productID = $pID;
 }
 public function generateOrder() {   
  if($this->qtyCheck()) {
   $this->addToCart();
   $this->calulateShipping();
   $this->applyDiscount();
   $this->placeOrder();
  }   
 }
 private function addToCart () {
  /* .. add product to cart .. */
 } 
 private function qtyCheck() {
  $qty = 'get product quantity from database';
  if($qty > 0) {
   return true;
  } else {
   return true;
  }
 }
  private function calulateShipping() {
  $shipping = new shippingCharge();
  $shipping->calculateCharge();
 }
 private function applyDiscount() {
  $discount = new discount();
  $discount->applyDiscount();
 }
 private function placeOrder() {
  $order = new order();
  $order->generateOrder();
 }
}
ログイン後にコピー

这样呢,我们的终端调用就可以两行解决:

$order = new productOrderFacade($productID);
$order->generateOrder();
ログイン後にコピー

示例四:往多个社交媒体同步消息的流程

// 发Twitter消息
class CodeTwit {
 function tweet($status, $url)
 {
 var_dump('Tweeted:'.$status.' from:'.$url);
 }
}
// 分享到Google plus上
class Googlize {
 function share($url)
 {
 var_dump('Shared on Google plus:'.$url);
 }
}
//分享到Reddit上
class Reddiator {
 function reddit($url, $title)
 {
 var_dump('Reddit! url:'.$url.' title:'.$title);
 }
}
ログイン後にコピー

如果每次我们写了一篇文章,想着转发到其他平台,都得分别去调用相应方法,这工作量就太大了,后期平台数量往往只增不减呢。这个时候借助于facade class:

class shareFacade {
 
 protected $twitter; 
 protected $google; 
 protected $reddit; 
 function construct($twitterObj,$gooleObj,$redditObj)
 {
 $this->twitter = $twitterObj;
 $this->google = $gooleObj;
 $this->reddit = $redditObj;
 } 
 function share($url,$title,$status)
 {
 $this->twitter->tweet($status, $url);
 $this->google->share($url);
 $this->reddit->reddit($url, $title);
 }
}
ログイン後にコピー

这样终端调用就可以:

$shareObj = new shareFacade($twitterObj,$gooleObj,$redditObj);
$shareObj->share('//myBlog.com/post-awsome','My greatest post','Read my greatest post ever.');
ログイン後にコピー

facade pattern的优劣势

优势

能够使你的终端调用与背后的子系统逻辑解耦,这往往发生在你的controller里,就意味着你的controller可以有更少的依赖,controller关注的更少了,从而责任和逻辑也更明确了,同时也意味着你子系统里的逻辑更改,并不会影响到你的controller里终端调用。

劣势

虽然特别有用,但是一个常见的陷阱就是,过度使用这个模式,明明可能那个时候你并不需要,这个往往注意即可。当然也有人争论说,明明我原来的代码都能用,干嘛费这个劲,那么同样是房子,你是喜欢住在精致的屋子里呢,还是说有四面墙就行了呢?

感觉facade pattern与其他的设计模式似曾相识?

认真学过我们《Laravel底层核心技术实战揭秘》这一课程的同学,可能到这里就会尤其觉得这个facade pattern好像在哪里见过?可能你会脱口而出:“这货跟之前咱们学的decorator pattern有啥区别呢?为啥不直接说成修饰者模式呢?”

确实,在“包装”逻辑方面,它们确实类似,但是:

修饰者模式(Decorator)——用来给一个Object添加、包裹上新的行为、逻辑,而不需要改动原来的代码

外观模式(facade pattern)——用来给一个或多个复杂的子系统、或者第三方库,提供统一的入口,或者说统一的终端调用方式

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

php与js打开本地exe应用程序传递参数步骤详解

如何实现php删除固定路径下文件夹与文件

以上がPHPでのファサードパターンの使い方の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Ubuntu および Debian 用の PHP 8.4 インストールおよびアップグレード ガイド Ubuntu および Debian 用の PHP 8.4 インストールおよびアップグレード ガイド Dec 24, 2024 pm 04:42 PM

PHP 8.4 では、いくつかの新機能、セキュリティの改善、パフォーマンスの改善が行われ、かなりの量の機能の非推奨と削除が行われています。 このガイドでは、Ubuntu、Debian、またはその派生版に PHP 8.4 をインストールする方法、または PHP 8.4 にアップグレードする方法について説明します。

PHP 開発用に Visual Studio Code (VS Code) をセットアップする方法 PHP 開発用に Visual Studio Code (VS Code) をセットアップする方法 Dec 20, 2024 am 11:31 AM

Visual Studio Code (VS Code とも呼ばれる) は、すべての主要なオペレーティング システムで利用できる無料のソース コード エディター (統合開発環境 (IDE)) です。 多くのプログラミング言語の拡張機能の大規模なコレクションを備えた VS Code は、

今まで知らなかったことを後悔している 7 つの PHP 関数 今まで知らなかったことを後悔している 7 つの PHP 関数 Nov 13, 2024 am 09:42 AM

あなたが経験豊富な PHP 開発者であれば、すでにそこにいて、すでにそれを行っていると感じているかもしれません。あなたは、運用を達成するために、かなりの数のアプリケーションを開発し、数百万行のコードをデバッグし、大量のスクリプトを微調整してきました。

PHPでHTML/XMLを解析および処理するにはどうすればよいですか? PHPでHTML/XMLを解析および処理するにはどうすればよいですか? Feb 07, 2025 am 11:57 AM

このチュートリアルでは、PHPを使用してXMLドキュメントを効率的に処理する方法を示しています。 XML(拡張可能なマークアップ言語)は、人間の読みやすさとマシン解析の両方に合わせて設計された多用途のテキストベースのマークアップ言語です。一般的にデータストレージに使用されます

JSON Web Tokens(JWT)とPHP APIでのユースケースを説明してください。 JSON Web Tokens(JWT)とPHP APIでのユースケースを説明してください。 Apr 05, 2025 am 12:04 AM

JWTは、JSONに基づくオープン標準であり、主にアイデンティティ認証と情報交換のために、当事者間で情報を安全に送信するために使用されます。 1。JWTは、ヘッダー、ペイロード、署名の3つの部分で構成されています。 2。JWTの実用的な原則には、JWTの生成、JWTの検証、ペイロードの解析という3つのステップが含まれます。 3. PHPでの認証にJWTを使用する場合、JWTを生成および検証でき、ユーザーの役割と許可情報を高度な使用に含めることができます。 4.一般的なエラーには、署名検証障害、トークンの有効期限、およびペイロードが大きくなります。デバッグスキルには、デバッグツールの使用とロギングが含まれます。 5.パフォーマンスの最適化とベストプラクティスには、適切な署名アルゴリズムの使用、有効期間を合理的に設定することが含まれます。

母音を文字列にカウントするPHPプログラム 母音を文字列にカウントするPHPプログラム Feb 07, 2025 pm 12:12 PM

文字列は、文字、数字、シンボルを含む一連の文字です。このチュートリアルでは、さまざまな方法を使用してPHPの特定の文字列内の母音の数を計算する方法を学びます。英語の母音は、a、e、i、o、u、そしてそれらは大文字または小文字である可能性があります。 母音とは何ですか? 母音は、特定の発音を表すアルファベットのある文字です。大文字と小文字など、英語には5つの母音があります。 a、e、i、o、u 例1 入力:string = "tutorialspoint" 出力:6 説明する 文字列「TutorialSpoint」の母音は、u、o、i、a、o、iです。合計で6元があります

PHPでの後期静的結合を説明します(静的::)。 PHPでの後期静的結合を説明します(静的::)。 Apr 03, 2025 am 12:04 AM

静的結合(静的::) PHPで後期静的結合(LSB)を実装し、クラスを定義するのではなく、静的コンテキストで呼び出しクラスを参照できるようにします。 1)解析プロセスは実行時に実行されます。2)継承関係のコールクラスを検索します。3)パフォーマンスオーバーヘッドをもたらす可能性があります。

PHPマジックメソッド(__construct、__destruct、__call、__get、__setなど)とは何ですか? PHPマジックメソッド(__construct、__destruct、__call、__get、__setなど)とは何ですか? Apr 03, 2025 am 12:03 AM

PHPの魔法の方法は何ですか? PHPの魔法の方法には次のものが含まれます。1。\ _ \ _コンストラクト、オブジェクトの初期化に使用されます。 2。\ _ \ _リソースのクリーンアップに使用される破壊。 3。\ _ \ _呼び出し、存在しないメソッド呼び出しを処理します。 4。\ _ \ _ get、dynamic属性アクセスを実装します。 5。\ _ \ _セット、動的属性設定を実装します。これらの方法は、特定の状況で自動的に呼び出され、コードの柔軟性と効率を向上させます。

See all articles