PHP実践デザインパターン [翻訳]
??> 元のアドレス:
PHP のデザイン パターン
この記事では主に、Web 開発、正確には PHP 開発における関連するデザイン パターンとその応用について説明します。経験豊富な開発者は確かにデザイン パターンに精通していますが、この記事は主に若手開発者を対象としています。まず、デザイン パターンとは何かを理解する必要があります。デザイン パターンは、リンク リストのような一般的なデータ構造でも、特別なアプリケーションやフレームワークのデザインでもありません。実際、デザイン パターンは次のように説明されます:
特定のコンテキストで一般的なデザインの問題を解決するためにカスタマイズされたオブジェクトとクラスの通信の説明
一方、デザイン パターンは、広く再利用可能な解決方法を提供します。日々のプログラミングでよく遭遇する問題。デザイン パターンは必ずしもクラス ライブラリやサードパーティのフレームワークである必要はなく、アイデアのようなものであり、システムで広く使用されています。これらは、さまざまなシナリオで問題を解決するために使用できるパターンまたはテンプレートとしても表示されます。デザイン パターンを使用すると、開発をスピードアップし、多くの大きなアイデアやデザインを簡単な方法で実装できます。もちろん、デザイン パターンは開発において非常に役立ちますが、不適切なシナリオでの誤用は避けなければなりません。
現在 23 の一般的な設計パターンがあり、さまざまな使用目標に応じて次の 3 つのカテゴリに分類できます:
作成パターン: オブジェクトを実装から分離するためにオブジェクトを作成するために使用されます。
アーキテクチャパターン: 異なるオブジェクト間に大きなオブジェクト構造を構築するために使用されます。
行動パターン: 異なるオブジェクト間のアルゴリズム、関係、責任を管理するために使用されます。
シングルトン (シングルトン モード)
シングルトン モードは、Web アプリケーションの開発において、実行時に特定のクラスにアクセス可能な作成を可能にするためによく使用されます。
<?php/** * Singleton class */final class Product{ /** * @var self */ private static $instance; /** * @var mixed */ public $mix; /** * Return self instance * * @return self */ public static function getInstance() { if (!(self::$instance instanceof self)) { self::$instance = new self(); } return self::$instance; } private function __construct() { } private function __clone() { }}$firstProduct = Product::getInstance();$secondProduct = Product::getInstance();$firstProduct->mix = 'test';$secondProduct->mix = 'example';print_r($firstProduct->mix);// exampleprint_r($secondProduct->mix);// example
多くの場合、システム内の複数のクラスに対してシングルトン構築メソッドを作成する必要があります。この方法で、一般的な抽象親ファクトリー メソッドを確立できます。
<?phpabstract class FactoryAbstract { protected static $instances = array(); public static function getInstance() { $className = static::getClassName(); if (!(self::$instances[$className] instanceof $className)) { self::$instances[$className] = new $className(); } return self::$instances[$className]; } public static function removeInstance() { $className = static::getClassName(); if (array_key_exists($className, self::$instances)) { unset(self::$instances[$className]); } } final protected static function getClassName() { return get_called_class(); } protected function __construct() { } final protected function __clone() { }}abstract class Factory extends FactoryAbstract { final public static function getInstance() { return parent::getInstance(); } final public static function removeInstance() { parent::removeInstance(); }}// using:class FirstProduct extends Factory { public $a = [];}class SecondProduct extends FirstProduct {}FirstProduct::getInstance()->a[] = 1;SecondProduct::getInstance()->a[] = 2;FirstProduct::getInstance()->a[] = 3;SecondProduct::getInstance()->a[] = 4;print_r(FirstProduct::getInstance()->a);// array(1, 3)print_r(SecondProduct::getInstance()->a);// array(2, 4)
レジストリ
登録デスク パターンはあまりありません。これは一般的な作成モードではなく、静的メソッドを使用してより簡単にデータにアクセスするためのものです。
<?php/*** Registry class*/class Package { protected static $data = array(); public static function set($key, $value) { self::$data[$key] = $value; } public static function get($key) { return isset(self::$data[$key]) ? self::$data[$key] : null; } final public static function removeObject($key) { if (array_key_exists($key, self::$data)) { unset(self::$data[$key]); } }}Package::set('name', 'Package name');print_r(Package::get('name'));// Package name
ファクトリ パターンは、その名前が示すように、非常によく使用されるもう 1 つのパターンです。これは確かにオブジェクト インスタンスの生産ファクトリーです。ある意味、ファクトリ パターンは、オブジェクトの特定の内部実装を気にせずにオブジェクトを取得するのに役立つ一般的なメソッドを提供します。
<?phpinterface Factory { public function getProduct();}interface Product { public function getName();}class FirstFactory implements Factory { public function getProduct() { return new FirstProduct(); }}class SecondFactory implements Factory { public function getProduct() { return new SecondProduct(); }}class FirstProduct implements Product { public function getName() { return 'The first product'; }}class SecondProduct implements Product { public function getName() { return 'Second product'; }}$factory = new FirstFactory();$firstProduct = $factory->getProduct();$factory = new SecondFactory();$secondProduct = $factory->getProduct();print_r($firstProduct->getName());// The first productprint_r($secondProduct->getName());// Second product
場合によっては、異なる選択ロジックに基づいて異なる構築ファクトリを提供する必要があり、複数のファクトリには統合された抽象ファクトリが必要です:
<?phpclass Config { public static $factory = 1;}interface Product { public function getName();}abstract class AbstractFactory { public static function getFactory() { switch (Config::$factory) { case 1: return new FirstFactory(); case 2: return new SecondFactory(); } throw new Exception('Bad config'); } abstract public function getProduct();}class FirstFactory extends AbstractFactory { public function getProduct() { return new FirstProduct(); }}class FirstProduct implements Product { public function getName() { return 'The product from the first factory'; }}class SecondFactory extends AbstractFactory { public function getProduct() { return new SecondProduct(); }}class SecondProduct implements Product { public function getName() { return 'The product from second factory'; }}$firstProduct = AbstractFactory::getFactory()->getProduct();Config::$factory = 2;$secondProduct = AbstractFactory::getFactory()->getProduct();print_r($firstProduct->getName());// The first product from the first factoryprint_r($secondProduct->getName());// Second product from second factory
Objectプールは、一連のオブジェクトを構築して保存し、必要に応じて呼び出しを取得するために使用できます:
<?phpclass Product { protected $id; public function __construct($id) { $this->id = $id; } public function getId() { return $this->id; }}class Factory { protected static $products = array(); public static function pushProduct(Product $product) { self::$products[$product->getId()] = $product; } public static function getProduct($id) { return isset(self::$products[$id]) ? self::$products[$id] : null; } public static function removeProduct($id) { if (array_key_exists($id, self::$products)) { unset(self::$products[$id]); } }}Factory::pushProduct(new Product('first'));Factory::pushProduct(new Product('second'));print_r(Factory::getProduct('first')->getId());// firstprint_r(Factory::getProduct('second')->getId());// second
特定の変数の遅延初期化もよく使用されます。クラス言語ではよく使用されません。どの関数が使用されるかがわかっており、一部の関数は多くの場合 1 回だけ必要になります。
<?phpinterface Product { public function getName();}class Factory { protected $firstProduct; protected $secondProduct; public function getFirstProduct() { if (!$this->firstProduct) { $this->firstProduct = new FirstProduct(); } return $this->firstProduct; } public function getSecondProduct() { if (!$this->secondProduct) { $this->secondProduct = new SecondProduct(); } return $this->secondProduct; }}class FirstProduct implements Product { public function getName() { return 'The first product'; }}class SecondProduct implements Product { public function getName() { return 'Second product'; }}$factory = new Factory();print_r($factory->getFirstProduct()->getName());// The first productprint_r($factory->getSecondProduct()->getName());// Second productprint_r($factory->getFirstProduct()->getName());// The first product
場合によっては、一部のオブジェクトを複数回初期化する必要があることがあります。特に初期化に多くの時間とリソースが必要な場合は、これらのオブジェクトを事前に初期化して保存してください。
<?phpinterface Product {}class Factory { private $product; public function __construct(Product $product) { $this->product = $product; } public function getProduct() { return clone $this->product; }}class SomeProduct implements Product { public $name;}$prototypeFactory = new Factory(new SomeProduct());$firstProduct = $prototypeFactory->getProduct();$firstProduct->name = 'The first product';$secondProduct = $prototypeFactory->getProduct();$secondProduct->name = 'Second product';print_r($firstProduct->name);// The first productprint_r($secondProduct->name);// Second product
Constructor パターンは、主にいくつかの複雑なオブジェクトの作成に関するものです:
<?phpclass Product { private $name; public function setName($name) { $this->name = $name; } public function getName() { return $this->name; }}abstract class Builder { protected $product; final public function getProduct() { return $this->product; } public function buildProduct() { $this->product = new Product(); }}class FirstBuilder extends Builder { public function buildProduct() { parent::buildProduct(); $this->product->setName('The product of the first builder'); }}class SecondBuilder extends Builder { public function buildProduct() { parent::buildProduct(); $this->product->setName('The product of second builder'); }}class Factory { private $builder; public function __construct(Builder $builder) { $this->builder = $builder; $this->builder->buildProduct(); } public function getProduct() { return $this->builder->getProduct(); }}$firstDirector = new Factory(new FirstBuilder());$secondDirector = new Factory(new SecondBuilder());print_r($firstDirector->getProduct()->getName());// The product of the first builderprint_r($secondDirector->getProduct()->getName());// The product of second builder
Decorator パターンを使用すると、実行時にさまざまなシナリオに基づいて特定のオブジェクトを動的に作成できます。オブジェクトが呼び出される前後の動作。
<?phpclass HtmlTemplate { // any parent class methods} class Template1 extends HtmlTemplate { protected $_html; public function __construct() { $this->_html = "<p>__text__</p>"; } public function set($html) { $this->_html = $html; } public function render() { echo $this->_html; }} class Template2 extends HtmlTemplate { protected $_element; public function __construct($s) { $this->_element = $s; $this->set("<h2>" . $this->_html . "</h2>"); } public function __call($name, $args) { $this->_element->$name($args[0]); }} class Template3 extends HtmlTemplate { protected $_element; public function __construct($s) { $this->_element = $s; $this->set("<u>" . $this->_html . "</u>"); } public function __call($name, $args) { $this->_element->$name($args[0]); }}
このモードでは、さまざまなインターフェイスを使用して特定のクラスを再構築することができ、さまざまな呼び出しメソッドの使用が可能になります:
<?phpclass SimpleBook { private $author; private $title; function __construct($author_in, $title_in) { $this->author = $author_in; $this->title = $title_in; } function getAuthor() { return $this->author; } function getTitle() { return $this->title; }}class BookAdapter { private $book; function __construct(SimpleBook $book_in) { $this->book = $book_in; } function getAuthorAndTitle() { return $this->book->getTitle().' by '.$this->book->getAuthor(); }}// Usage$book = new SimpleBook("Gamma, Helm, Johnson, and Vlissides", "Design Patterns");$bookAdapter = new BookAdapter($book);echo 'Author and Title: '.$bookAdapter->getAuthorAndTitle();function echo $line_in) { echo $line_in."<br/>";}
テスト モードは主に、クライアント クラスが特定の実装を知らなくても特定のアルゴリズムをより適切に使用できるようにするためです。
<?phpinterface OutputInterface { public function load();}class SerializedArrayOutput implements OutputInterface { public function load() { return serialize($arrayOfData); }}class JsonStringOutput implements OutputInterface { public function load() { return json_encode($arrayOfData); }}class ArrayOutput implements OutputInterface { public function load() { return $arrayOfData; }}
他のオブジェクトが何らかの方法でオブザーバーとして登録できるようにすることで、オブジェクトを監視可能に設定できます。観察されるオブジェクトが変化するたびに、メッセージが観察者に送信されます。
<?phpinterface Observer { function onChanged($sender, $args);}interface Observable { function addObserver($observer);}class CustomerList implements Observable { private $_observers = array(); public function addCustomer($name) { foreach($this->_observers as $obs) $obs->onChanged($this, $name); } public function addObserver($observer) { $this->_observers []= $observer; }}class CustomerListLogger implements Observer { public function onChanged($sender, $args) { echo( "'$args' Customer has been added to the list \n" ); }}$ul = new UserList();$ul->addObserver( new CustomerListLogger() );$ul->addCustomer( "Jack" );
このモデルは別名、制御連鎖モデルとも呼ばれます。これは主に、特定のコマンドに対する一連のプロセッサで構成され、各クエリはプロセッサによって形成された一連の責任の中で渡され、プロセッサは応答して処理する必要があるかどうかを判断します。プロセッサがリクエストを処理できる間、各ハンドラは一時停止されます。
リーリー

ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

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

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

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

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

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

ホットトピック









PHPクライアントURL(CURL)拡張機能は、開発者にとって強力なツールであり、リモートサーバーやREST APIとのシームレスな対話を可能にします。尊敬されるマルチプロトコルファイル転送ライブラリであるLibcurlを活用することにより、PHP Curlは効率的なexecuを促進します

顧客の最も差し迫った問題にリアルタイムでインスタントソリューションを提供したいですか? ライブチャットを使用すると、顧客とのリアルタイムな会話を行い、すぐに問題を解決できます。それはあなたがあなたのカスタムにより速いサービスを提供することを可能にします

記事では、PHP 5.3で導入されたPHPの後期静的結合(LSB)について説明し、より柔軟な継承を求める静的メソッドコールのランタイム解像度を可能にします。 LSBの実用的なアプリケーションと潜在的なパフォーマ

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

記事では、入力検証、認証、定期的な更新など、脆弱性から保護するためのフレームワークの重要なセキュリティ機能について説明します。

この記事では、フレームワークにカスタム機能を追加し、アーキテクチャの理解、拡張ポイントの識別、統合とデバッグのベストプラクティスに焦点を当てています。

PHP開発でPHPのCurlライブラリを使用してJSONデータを送信すると、外部APIと対話する必要があることがよくあります。一般的な方法の1つは、Curlライブラリを使用して投稿を送信することです。
