ホームページ  >  記事  >  バックエンド開発  >  PHP_PHP チュートリアルの 12 のデザイン パターン

PHP_PHP チュートリアルの 12 のデザイン パターン

WBOY
WBOYオリジナル
2016-07-13 09:51:47874ブラウズ

PHP 12 のデザインパターン

PSR-0仕様の設計ベース
1. すべてに名前空間を使用します
2. すべての PHP ファイルは include/require なしで自動的にロードされる必要があります
spl_autoload_register
3.シングル入場モード




1. 基本デザイン3パターン
ファクトリーモード
工場出荷時の方法で新しいものと交換してください


クラスファクトリー{

静的関数 createDatabase(){
$db = 新しいデータベース;
$db を返します;
}
}
使用する場合は、 $db = Factory::createDatabase(); を使用できます




シングルトンパターン
クラスデータベース{
プライベート $db;


プライベート関数 __construct(){
//ここにデータベースに接続するための書き込みができます
}


静的関数 getInstance(){
if(self::$db){
自分自身を返す::$db;
}その他{
self::$db=新しいself()
return self::$db;//private は単独で呼び出すことができます
}
}


関数 where(){




}


}


ファクトリープラスシングルトンモードの場合
クラスファクトリー{

静的関数 createDatabase(){
$db = データベース::getInstance();
$db を返します;
}
}


レジストラ (ツリー) モード
クラス登録{
保護された静的 $object;
静的関数セット($alias,$object){
self::$object[$alias]=$object;


}
静的関数 get($name)
{
return self::$object[$name];
}
function _unset($alias){
unset(self::$object[$alias]);
}
}
ファクトリーメソッドとの組み合わせ
クラスファクトリー{

静的関数 createDatabase(){
$db = データベース::getInstance();
登録::set('db1',$db);
$db を返します;
}
}
呼び出しを直接インデックス化します
$db = 登録::get('db1');


アダプターモード
1. アダプターモードは、完全に異なる機能インターフェイスを統合 API にカプセル化できます
2. 実践的なアプリケーション例として、PHP データベース操作には、mysql、mysqli、pdo が含まれます。アダプター モードを使用できます
。 一貫性への統合。同様のシナリオには、memcache、redis、file、apc などのさまざまなキャッシュ機能を一貫性へ統合するキャッシュ アダプターが含まれます。 たとえば、Database.php にはインターフェースがあります
インターフェースIDatabase
{
関数 connect($host,$user,$pwd,$dbname);
関数クエリ($sql);
関数 close();
}


以下の3つのカテゴリがあります
クラス mysql は IDatabase{
を実装します プライベート $con;
関数 connect($host,$user,$pwd,$dbname){
$this->con = mysql_connect($host,$user,$pwd);
mysql_select_db($dbname,$this->con);
}
関数クエリ($sql){
return mysql_query($sql,$this->con);
}
関数 close(){
return mysql_close($this->con);
}
}


クラス mysqli は IDatabase{
を実装します 保護された $con;
関数 connect($host,$user,$pwd,$dbname)
{
$this->con = mysqli_connect($host,$user,$pwd,$dbname);
}
関数クエリ($sql)
{
return mysqli_query($this->con,$sql);
}
関数close()
{
return mysqli_close($this->con);
}
}


クラス PDO は IDatabase{
を実装します 保護された $con;
関数 connect($host,$user,$pwd.$dbname)
{
$con = 新しい PDO("mysql:host=$host;dbname=$dbname",$user,$pwd);
$this->con=$con;
}
関数クエリ($sql){
return $this->con->query($sql);
}
関数 close(){
unset($this->con);
}
}
それで、私たちが電話するとき
$db = 新しい mysql() または新しい PDO();
$db->connect('127.0.0.1','root','root');
$db->query();
$db->close();


戦略モード
特定の動作とアルゴリズムのセットをクラスにカプセル化し、特定の特定のコンテキストに適応させるこのパターンが戦略パターンです
。 電子商取引システムのウェブサイトシステムで、男性ユーザーと女性ユーザーがそれぞれ異なる商品カテゴリにジャンプする必要がある場合の実用的な適用距離
まず戦略インターフェースファイルを宣言します
インターフェイス UserStrategy{
関数 showAd();
関数 showcategory();
}


//最初の戦略は女性ユーザー向けです
クラス女性UserStrategyはUserStrategyを実装します{
関数 showAd(){
echo '2014 新作婦人服';
}
関数 showCategory()
{
「婦人服」をエコー;
}
}
// 2 番目の戦略は男性ユーザー向けです
クラス MaleUserStrategy は UserStrategy{
を実装します 関数 showAd(){
echo '2014 新しい紳士服';
}
関数 showCategory()
{
「紳士服」をエコーし​​ます;
}
}
//ページクラスがある場合
クラスページ{
保護された $strategy;
関数インデックス(){
$this->strategy->showAd();
$this->strategy->showCategory();
}


function setStrategy(UserStrategt $strategy){
$this->strategy=$strategy;
}
}
$page = 新しいページ();
if(isset($_GET['女性'])){
$strategy = new FemaleUserStrategy();
}その他{
$strategy = new MaleUserStrategy();
}
$page->setStrategy($strategy);
$page->index();
ハードコーディングされたモデルから分離されたモデルへ


データオブジェクトマッピングパターン
データ オブジェクト マッピング モードは、オブジェクトとデータ ストレージを
にマップします。 オブジェクトの操作は、データ ストア上の操作にマップされます。
コードでデータ オブジェクト マッピング モードを実装するには、複雑な SQL ステートメントをオブジェクト属性操作にマップする ORM クラスを実装します
クラス ユーザー{
パブリック $id;
パブリック $name;
パブリック $mobile;
パブリック $regtime;
保護された $db;
関数 __construct($id){
// まずデータを取得します
$this->db = 新しい mysql();
$this->db->connect('xxxxx'xxxx);
$res = $this->db->query('select * from XXX where id = {$id}');
$data = $res->fetch_assoc();


$this->id=$data['id'];
$this->name=$data['name'];
$this->mobile=$data['mobile'];
$this->regtime=$data['regtime'];
$res を返します;
}


関数 __destruct(){
//修正として使用できます
$this->db->query('update xx set name={$this->name} mobile={$this->mobile}XXXXX where id = {$this->id}');
}
}


$user = new User(1);//1 はデータベース内の ID が 1 つであることに対応します
$user->mobile = '155555555';
$user->name='テスト';
$user->regtime=time();
// ここには SQL ステートメントはありません。オブジェクトに対する操作のみです


包括的なアプリケーション (ファクトリーモード、レジストラーモード、アダプターモード)



と オブザーバーモード
1. オブザーバー パターン。オブジェクトの状態が変化すると、それに依存するすべてのオブジェクトが通知を受け取り、自動的に更新されます。
2. シナリオ: イベントが発生した後、一連の更新操作を実行する必要があります。従来のプログラミング方法は
です。 イベントコードの直後に処理ロジックを追加するため、更新ロジックが増えるとコードの保守が難しくなります
。 新しいロジックを追加するには、イベント本体のコードを変更する必要があります
3. オブザーバー パターンは、低結合で非侵入的な通知更新メカニズムを実装します。
デモ
クラスイベント{
関数トリガー(){
echo "Event";// イベントが発生したことを示します


//更新ロジックの作成を開始します
エコー「論理 1」;

エコー 'ロジック 2';


エコー「ロジック 3」;


}
}


$event = new Event();//従来の方法は結合されており煩雑です
//ソースコードを変更する必要があるため、オブザーバーパターンを定義します
デモ
//インターフェイスが登場します
//最初に基本抽象クラスが来ます
抽象クラス EventGenerator{
プライベート $observers = array();
関数 addObserver(Observer$observer){
$this->oververs[]=$oberver;
}
関数notify(){
foreach($this->oververs as $observer)
{
$observer->updata();
}
}
}
インターフェースオーバーバー{
関数更新($event_info = null);
}
//したがって、現時点では、この基本クラスを継承する Event クラスが必要です
class Event extends EventGenerator{
関数トリガー(){
echo "Event";// イベントが発生したことを示します
$this->notify();
}
}


クラス Observer1 は Observer{
を実装します 関数更新($event_info=null)
{
エコー「ロジック 1」;
}
}


class Oberver2 は Oberver を実装します{
関数更新($event_info=null)
{
エコー「ロジック 2」;
}
}




プロトタイプモード
1. ファクトリーモードと同様に、オブジェクトの作成に使用されます
2. プロトタイプモードはファクトリーモードの実装と異なり、まずプロトタイプを作成します
オブジェクトを作成し、プロトタイプ オブジェクトをクローンして新しいオブジェクトを作成すると、クラスが不要になります
作成中に初期化操作が繰り返される
3. プロトタイプモードは、大きなオブジェクトの作成に適しています。大きなオブジェクトを作成するたびに、大量のコストがかかります。 プロトタイプ モードではメモリのみがコピーされます。
Canvas クラスがあるとします。新しいのは複雑です
あと2回くらい使いたい
このようにして、プロトタイプ モードを使用して new の問題を解決し、クローンを使用して new を置き換えることができます
初期化後に直接クローンを作成するだけです。


デコレータパターン
1. デコレータ モードでは、クラス関数を動的に追加および変更できます。
2. クラスは関数を提供します。追加の関数を変更したい場合は、従来の
を使用します。 プログラミング モードでは、サブクラスを作成して継承し、クラス メソッドを再実装する必要があります。
3. デコレータ モードを使用すると、実行時にデコレータ オブジェクトを追加するだけで最大限の柔軟性を実現できます
Canvas クラスがある場合。色を追加したい場合、印刷できる正方形は 1 つだけです
通常、サブクラスを作成し、そのキャンバス クラスを継承します。
キャンバスを生成するメソッドをオーバーライドします。では、たくさんの機能を追加したい場合はどうすればよいでしょうか?
多くのクラスを書き直す必要がありますか?
次に、デコレータ パターンを使用してこの問題を解決します
まず、キャンバス デコレータ インターフェイスを宣言しましょう
インターフェイス DrawDecorator{
関数 beforeDraw();
関数 afterDraw();
}


たとえば、キャンバスクラスのdraw()メソッドを変更する必要があります
そこで、draw() メソッドで
を呼び出します。 関数描画(){
$this->beforeDraw();
//元のコードの内容はこちら
$this->afterDraw();
}
次に、protected $decorators[]=array();
をキャンバス クラスに追加します。 デコレーターインターフェイスを受け取るメソッドを追加します
関数 addDecorator(DrawDecorator $decorator){
$this->decorators[]=$decorator;
}
デコレーターを呼び出すメソッドをさらに 2 つ追加します
関数 beforeDraw(){
foreach($this->decorators as $decorator)
{
$decorator->beforeDraw();
}
}


関数 afterDraw(){
//逆、後入れ先出し
$decorators = array_reverse($this->decorators);
foreach($decorators として $decorator)
{
$decorator->afterDraw();
}
}


カラーデコレーターがいます
クラス ColorDrawDecorator は DrawDecorator を実装します{
保護された $color;
関数 __construct($color='red')
{
$this->color= $color;
}
beforeDraw() 関数
{
echo "
";
}
関数 afterDraw()
{
エコー「
」「
}
}
ここで実装するために継承する必要はありません
$a = new Canvas();//キャンバスクラスをインスタンス化します
$a -> init();//初期化
$a -> addDecorator(new colorDrawDecorator('green'));//カラーデコレータクラスを追加します
イテレーターパターン
1. イテレーターモード、内部実装を知らずに yige を走査します
集合オブジェクトの内部要素
2. 従来のプログラミングモデルと比較して、反復子パターンは要素を走査するために必要な操作を隠すことができます
たとえば、データベースを走査してすべてのオブジェクトを取得します
クラス Alluser はイテレーターを実装します{
保護された $id;
protected $index;//イテレータの現在位置
protected $data=array();
//Iterator はイテレータインターフェイスです
関数 __construct(){
$db = Factory::getDatabase();
$result = $db->query("ユーザーからの選択 ID");
$this->ids = $db->mysql_fetch_assoc($result);
}
関数 current(){
// 現在の要素を取得します
$id=$this->ids[$this->index]['id'];
return Factory::getUser($id);
}
関数 next(){
//次の要素
$this->index ++;
}
関数有効()
{
//データがあるかどうかを判定します
return $this->index ids);
}
関数 rewind(){
$this->index=0;//始まりへの第一歩
}
ファンクションキー(){
// 現在のインデックスを取得します
$this->index を返す;
}
}
$users = new Alluser();
foreach ($users として $user)
{
var_dump($user);
}
エージェントモード
1. クライアントとエンティティの間にプロキシ オブジェクト (プロキシ) を確立し、クライアントはエンティティに対するすべての操作をプロキシ オブジェクトに委任し、エンティティの特定の実装の詳細を隠します。
一つだけ書いてください


オブジェクト指向プログラミングの基本原則
1. 単一の責任: クラスは 1 つのことだけを行う必要があります
2. オープンとクローズ: クラスは拡張可能である必要がありますが、変更はできません
3. 依存関係の逆転: あるクラスが別のクラスに強く依存するべきではありません。各クラスは別のクラスに置き換え可能です
。 4. 構成: ハードコーディングの代わりに、可能な限り構成を使用します。
5. インターフェイス指向プログラミング: 実装ではなく、インターフェイスのみを考慮する必要があります。


MVC アーキテクチャの原則
まず新しい Config オブジェクトを作成しましょう
$config = 新しい構成(__DIR__.'/configs');
$config['コントローラー'];


次に、Config クラスがあります
クラス Config は ArrayAccess{
を実装します //ArrayAccess インターフェースは組み込みインターフェースです。つまり、配列値の受け渡しが許可されており、実装するメソッドは 4 つあります
保護された $path;
protected $configs=array();
関数 __construct($path)
{
$this->path=$path;
}
関数 offsetGet($key){
//設定配列ファイル名のキーを取得します
if(empty($this->configs[$key]))
//配列ファイル名が元の設定ファイルに存在しない場合は、それをロードします
{
$file_path=$this->path.'/'.$key.'.php';//読み込みパスを生成します
$config = $file_path が必要;
$this->config[$key]=$config;
}
return $this->configs[$key];


}
関数 offsetSet($key,$value)
{
//配列のキーを設定します
}
関数 offsetExists($key)
{ //配列のキーが存在するか確認します
return isset($this->configs[$key]);
}
関数 offsetUnset($key)
{ //配列のキーを削除します

}
}


controller.phpなどの設定ファイル
$config = 配列(
'ホーム'=>配列(
'デコレータ'=>配列(
'IMoocDectoratorTemplate'、
)、
)、
);


構成とデザインパターン
1. PHP で ArrayAccess を使用して構成ファイルをロードします
2. ファクトリメソッドで設定を読み取り、設定可能なオブジェクトを生成します
3. デコレーター モードを使用して、権限の検証、テンプレートのレンダリング、JSON のシリアル化を実装します
4. オブザーバー パターンを使用して、データ更新イベントの一連の更新操作を実装します
5. プロキシモードを使用してデータベースの自動マスター/スレーブ切り替えを実現します

www.bkjia.comtru​​ehttp://www.bkjia.com/PHPjc/1011354.html技術記事 PHP 12 の設計パターン PSR-0 仕様の設計基盤 1. すべて名前空間を使用する 2. すべての PHP ファイルは自動的にロードされる必要があり、spl_autoload_register を含めたり要求したりすることはできません 3. シングル エントリ モード...
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。