PHP常用六大設計モード

40842 ワード

単一モード
特徴:
三私一公:プライベート静的変数(インスタンスの保存)、プライベート構造方法(インスタンスの作成防止)、プライベートクローン方法(クローンオブジェクトの防止)、パブリック静的方法(外部にインスタンスを提供する)
適用シーン:
プログラムアプリケーションでは、データベース操作に関わる場合、操作するたびにデータベースに接続すると、大量のリソース消費をもたらします.単一のインスタンス・モードで、一意のデータベース接続オブジェクトを作成できます.

class Singleton
{
    private static $_instance;
    private function __construct(){}
    private function __clone(){}
    public static function getInstance()
    {
        if(self::$_instance instanceof Singleton){//instanceof                
            self::$_instance = new Singleton();
        }
        return self::$_instance;
    }
}

工場モード
特徴:
呼び出しオブジェクトと作成オブジェクトを分離し、呼び出し者が直接工場に要求し、コードの結合を減らす.システムの保守性と拡張性を向上させる.
適用シーン:
オブジェクトを作成するいくつかの方法があり、newを直接使用せずにファクトリクラスを使用してオブジェクトを作成できます.これにより、作成したオブジェクトのタイプを変更するには、ファクトリを変更するだけです.
//  3       
class Aclass
{

}
class Bclass
{

}
class Cclass
{

}
class Factory
{
    //        
    const ACLASS = 'Aclass';
    const BCLASS = 'Bclass';
    const CCLASS = 'Cclass';
    public static function getInstance($newclass)
    {
        $class = $newclass;//                ,    。
        return new $class;
    }
}
//    :
Factory::getInstance(Factory::ACLASS);

登録ツリーモード
特徴:
登録ツリーモードオブジェクトインスタンスをグローバルなオブジェクトツリーに登録し、必要に応じてオブジェクトツリーから抽出するモード設計方法.
適用:
単一のモデルでもファクトリモデルでも、両方を組み合わせて生成されたオブジェクトでも、登録ツリーに「挿入」されます.あるオブジェクトを使うときは、登録木から直接取ればいいです.これは、グローバル変数を使用するのと同じように便利で実用的です.また、登録ツリーモードは、他のモードに非常に良いアイデアを提供しています.(以下の例は、単例、ファクトリ、登録ツリーの併用)
//    
class Single{
    public $hash;
    static protected $ins=null;
    final protected function __construct(){
        $this->hash=rand(1,9999);
    }

    static public function getInstance(){
        if (self::$ins instanceof self) {
            return self::$ins;
        }
        self::$ins=new self();
        return self::$ins;
    }
}

//    
class RandFactory{
    public static function factory(){
        return Single::getInstance();
    }
}

//   
class Register{
    protected static $objects;
    public static function set($alias,$object){
        self::$objects[$alias]=$object;
    }
    public static function get($alias){
        return self::$objects[$alias];
    }
    public static function _unset($alias){
        unset(self::$objects[$alias]);
    }
}
//  
Register::set('rand',RandFactory::factory());
$object=Register::get('rand');
print_r($object);

ポリシー・モード
定義:
一連のアルゴリズムを定義し、各アルゴリズムをカプセル化し、互いに置き換えることができます.ポリシー・モードは、アルゴリズムを使用するお客様とは独立して変化させます.
特徴:
ポリシー・モードは、関連するアルゴリズム・ファミリーを管理する方法を提供します.ポリシー・モードは、継承関係を置き換える方法を提供します.ポリシー・モードを使用すると、複数の条件を使用して文を転送することを回避できます.
適用シーン:
複数のクラスは、表現動作が異なる場合にのみ区別され、Strategyモードを使用して、実行時に具体的に実行する動作を動的に選択できます.例えば学校に行くには、歩く、バス、地下鉄...
abstract class Strategy
{
    abstract function goSchool();
}
class Run extends Strategy
{
    public function goSchool()
    {
        // TODO: Implement goSchool() method.
    }
}
class Subway extends Strategy
{
    public function goSchool()
    {
        // TODO: Implement goSchool() method.
    }
}
class Bike extends Strategy
{
    public function goSchool()
    {
        // TODO: Implement goSchool() method.
    }
}
class Context
{
    protected $_stratege;//          
    public function goSchoole()
    {
        $this->_stratege->goSchoole();
    }
}
//  :
$contenx = new Context();
$avil_stratery = new Subway();
$contenx->goSchoole($avil_stratery);

アダプタモード
特徴:
さまざまな異なる関数インタフェースを統合されたAPIにカプセル化します.
適用:
PHPのデータベース操作はMySQL、MySQLi、PDOの3種類があり、アダプタモードで統一し、異なるデータベース操作を同じAPIに統一することができます.似たようなシーンにはcacheアダプタもあり、memcache、redis、file、apcなどの異なるキャッシュ関数を一致させることができます.
abstract class Toy
{
    public abstract function openMouth();

    public abstract function closeMouth();
}

class Dog extends Toy
{
    public function openMouth()
    {
        echo "Dog open Mouth
"
; } public function closeMouth() { echo "Dog close Mouth
"
; } } class Cat extends Toy { public function openMouth() { echo "Cat open Mouth
"
; } public function closeMouth() { echo "Cat close Mouth
"
; } } // ( ) interface RedTarget { public function doMouthOpen(); public function doMouthClose(); } // ( ) interface GreenTarget { public function operateMouth($type = 0); } // ( ) class RedAdapter implements RedTarget { private $adaptee; function __construct(Toy $adaptee) { $this->adaptee = $adaptee; } // Adaptee sampleMethod1 public function doMouthOpen() { $this->adaptee->openMouth(); } public function doMouthClose() { $this->adaptee->closeMouth(); } } // ( ) class GreenAdapter implements GreenTarget { private $adaptee; function __construct(Toy $adaptee) { $this->adaptee = $adaptee; } // Adaptee:GreenTarget operateMouth public function operateMouth($type = 0) { if ($type) { $this->adaptee->openMouth(); } else { $this->adaptee->closeMouth(); } } } class testDriver { public function run() { // $adaptee_dog = new Dog(); echo "
"
; $adapter_red = new RedAdapter($adaptee_dog); // $adapter_red->doMouthOpen(); // $adapter_red->doMouthClose(); echo "
"
; $adapter_green = new GreenAdapter($adaptee_dog); // $adapter_green->operateMouth(1); // $adapter_green->operateMouth(0); } } // $test = new testDriver(); $test->run();

オブザーバモード
特徴:
オブザーバーモード(Observer)では、1つのオブジェクトの状態が変化すると、それに依存するオブジェクトがすべて通知され、自動的に更新されます.観察者モードは低結合,非侵入式の通知と更新機構を実現した.
適用:
1つのイベントが発生した後、一連の更新操作を実行します.従来のプログラミング方式は,イベントのコードの後に直接処理を加える論理である.更新のロジックが増えると、コードのメンテナンスが難しくなります.この方式は結合され,侵入的であり,新しい論理を増加させるにはイベントの本体コードを修正する必要がある.
//     
interface Subject{
    public function register(Observer $observer);
    public function notify();
}
//      
interface Observer{
    public function watch();
}
//   
class Action implements Subject{
    public $_observers=[];
    public function register(Observer $observer){
        $this->_observers[]=$observer;
    }

    public function notify(){
        foreach ($this->_observers as $observer) {
            $observer->watch();
        }

    }
}

//    
class Cat1 implements Observer{
    public function watch(){
        echo "Cat1 watches TV
"
; } } class Dog1 implements Observer{ public function watch(){ echo "Dog1 watches TV
"
; } } class People implements Observer{ public function watch(){ echo "People watches TV
"
; } } // $action=new Action(); $action->register(new Cat1()); $action->register(new People()); $action->register(new Dog1()); $action->notify();