1. 程式人生 > >php的23種設計模式

php的23種設計模式

PhpDesignPatterns 【PHP 中的設計模式】

一、 Introduction【介紹】

設計模式:提供了一種廣泛的可重用的方式來解決我們日常程式設計中常常遇見的問題。設計模式並不一定就是一個類庫或者第三方框架,它們更多的表現為一種思想並且廣泛地應用在系統中。它們也表現為一種模式或者模板,可以在多個不同的場景下用於解決問題。設計模式可以用於加速開發,並且將很多大的想法或者設計以一種簡單地方式實現。當然,雖然設計模式在開發中很有作用,但是千萬要避免在不適當的場景誤用它們。

二、 Category【分類】

根據目的和範圍,設計模式可以分為五類。
按照目的分為:建立設計模式,結構設計模式,以及行為設計模式。
按照範圍分為:類的設計模式,以及物件設計模式。

1. 按照目的分,目前常見的設計模式主要有23種,根據使用目標的不同可以分為以下三大類:

  • 建立設計模式(Creational Patterns)(5種):用於建立物件時的設計模式。更具體一點,初始化物件流程的設計模式。當程式日益複雜時,需要更加靈活地建立物件,同時減少建立時的依賴。而建立設計模式就是解決此問題的一類設計模式。

    • 單例模式【Singleton】
    • 工廠模式【Factory】
    • 抽象工廠模式【AbstractFactory】
    • 建造者模式【Builder】
    • 原型模式【Prototype】
  • 結構設計模式(Structural Patterns)(7種):用於繼承和介面時的設計模式。結構設計模式用於新類的函式方法設計,減少不必要的類定義,減少程式碼的冗餘。

    • 介面卡模式【Adapter】
    • 橋接模式【Bridge】
    • 合成模式【Composite】
    • 裝飾器模式【Decorator】
    • 門面模式【Facade】
    • 代理模式【Proxy】
    • 享元模式【Flyweight】
  • 行為模式(Behavioral Patterns)(11種):用於方法實現以及對應演算法的設計模式,同時也是最複雜的設計模式。行為設計模式不僅僅用於定義類的函式行為,同時也用於不同類之間的協議、通訊。

    • 策略模式【Strategy】
    • 模板方法模式【TemplateMethod】
    • 觀察者模式【Observer】
    • 迭代器模式【Iterator】
    • 責任鏈模式【ResponsibilityChain】
    • 命令模式【Command】
    • 備忘錄模式【Memento】
    • 狀態模式【State】
    • 訪問者模式【Visitor】
    • 中介者模式【Mediator】
    • 直譯器模式【Interpreter】

2.按照範圍分為:類的設計模式,以及物件設計模式

  • 類的設計模式(Class patterns):用於類的具體實現的設計模式。包含了如何設計和定義類,以及父類和子類的設計模式。

  • 物件設計模式(Object patterns): 用於物件的設計模式。與類的設計模式不同,物件設計模式主要用於執行期物件的狀態改變、動態行為變更等。

三、 DesignPatternsPrinciple【設計模式原則】

設計模式六大原則

  • 開放封閉原則:一個軟體實體如類、模組和函式應該對擴充套件開放,對修改關閉。
  • 里氏替換原則:所有引用基類的地方必須能透明地使用其子類的物件.
  • 依賴倒置原則:高層模組不應該依賴低層模組,二者都應該依賴其抽象;抽象不應該依賴細節;細節應該依賴抽象。
  • 單一職責原則:不要存在多於一個導致類變更的原因。通俗的說,即一個類只負責一項職責。
  • 介面隔離原則:客戶端不應該依賴它不需要的介面;一個類對另一個類的依賴應該建立在最小的介面上。
  • 迪米特法則:一個物件應該對其他物件保持最少的瞭解。

四、 Realization【設計模式實現】

Creational Patterns(建立設計模式)

1. Singleton(單例模式)

  • Singleton(單例模式):單例模式是最常見的模式之一,在Web應用的開發中,常常用於允許在執行時為某個特定的類建立僅有一個可訪問的例項。
<?php

/**
 * Singleton class[單例模式]
 * @author ITYangs<[email protected].com>
 */
final class Mysql
{

    /**
     *
     * @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,防止建立物件
     */
    private function __construct()
    {}

    /**
     * 防止物件被複制
     */
    private function __clone()
    {
        trigger_error('Clone is not allowed !');
    }
}

// @test
$firstMysql = Mysql::getInstance();
$secondMysql = Mysql::getInstance();

$firstMysql->mix = 'ityangs_one';
$secondMysql->mix = 'ityangs_two';

print_r($firstMysql->mix);
// 輸出: ityangs_two
print_r($secondMysql->mix);
// 輸出: ityangs_two

在很多情況下,需要為系統中的多個類建立單例的構造方式,這樣,可以建立一個通用的抽象父工廠方法:

<?php
/**
 * Singleton class[單例模式:多個類建立單例的構造方式]
 * @author ITYangs<[email protected]>
 */
abstract class FactoryAbstract {

    protected static $instances = array();

    public static function getInstance() {
        $className = self::getClassName();
        if (!(self::$instances[$className] instanceof $className)) {
            self::$instances[$className] = new $className();
        }
        return self::$instances[$className];
    }

    public static function removeInstance() {
        $className = self::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();
    }
}
// @test

class FirstProduct extends Factory {
    public $a = [];
}
class SecondProduct extends FirstProduct {
}

FirstProduct::getInstance()->a[] = 1;
SecondProduct::getInstance()->a[] = 2;
FirstProduct::getInstance()->a[] = 11;
SecondProduct::getInstance()->a[] = 22;

print_r(FirstProduct::getInstance()->a);
// Array ( [0] => 1 [1] => 11 )
print_r(SecondProduct::getInstance()->a);
// Array ( [0] => 2 [1] => 22 )

2. Factory(工廠模式)

工廠模式是另一種非常常用的模式,正如其名字所示:確實是物件例項的生產工廠。某些意義上,工廠模式提供了通用的方法有助於我們去獲取物件,而不需要關心其具體的內在的實現。

<?php

/**
 * Factory class[工廠模式]
 * @author ITYangs<[email protected]>
 */
interface SystemFactory
{
    public function createSystem($type);
}

class MySystemFactory implements SystemFactory
{
    // 實現工廠方法
    public function createSystem($type)
    {
        switch ($type) {
            case 'Mac':
                return new MacSystem();
            case 'Win':
                return new WinSystem();
            case 'Linux':
                return new LinuxSystem();
        }
    }
}

class System{ /* ... */}
class WinSystem extends System{ /* ... */}
class MacSystem extends System{ /* ... */}
class LinuxSystem extends System{ /* ... */}

//建立我的系統工廠
$System_obj = new MySystemFactory();
//用我的系統工廠分別建立不同系統物件
var_dump($System_obj->createSystem('Mac'));//輸出:object(MacSystem)#2 (0) { }
var_dump($System_obj->createSystem('Win'));//輸出:object(WinSystem)#2 (0) { }
var_dump($System_obj->createSystem('Linux'));//輸出:object(LinuxSystem)#2 (0) { }

3. AbstractFactory(抽象工廠模式)

有些情況下我們需要根據不同的選擇邏輯提供不同的構造工廠,而對於多個工廠而言需要一個統一的抽象工廠:

<?php

class System{}
class Soft{}

class MacSystem extends System{}
class MacSoft extends Soft{}

class WinSystem extends System{}
class WinSoft extends Soft{}


/**
 * AbstractFactory class[抽象工廠模式]
 * @author ITYangs<[email protected]>
 */
interface AbstractFactory {
    public function CreateSystem();
    public function CreateSoft();
}

class MacFactory implements AbstractFactory{
    public function CreateSystem(){ return new MacSystem(); }
    public function CreateSoft(){ return new MacSoft(); }
}

class WinFactory implements AbstractFactory{
    public function CreateSystem(){ return new WinSystem(); }
    public function CreateSoft(){ return new WinSoft(); }
}






//@test:建立工廠->用該工廠生產對應的物件

//建立MacFactory工廠
$MacFactory_obj = new MacFactory();
//用MacFactory工廠分別建立不同物件
var_dump($MacFactory_obj->CreateSystem());//輸出:object(MacSystem)#2 (0) { }
var_dump($MacFactory_obj->CreateSoft());// 輸出:object(MacSoft)#2 (0) { }


//建立WinFactory
$WinFactory_obj = new WinFactory();
//用WinFactory工廠分別建立不同物件
var_dump($WinFactory_obj->CreateSystem());//輸出:object(WinSystem)#3 (0) { }
var_dump($WinFactory_obj->CreateSoft());//輸出:object(WinSoft)#3 (0) { }

4. Builder(建造者模式)

建造者模式主要在於建立一些複雜的物件。將一個複雜物件的構造與它的表示分離,使同樣的構建過程可以建立不同的表示的設計模式;

結構圖:
這裡寫圖片描述

<?php
/**
 * 
 * 產品本身
 */
class Product { 
    private $_parts; 
    public function __construct() { $this->_parts = array(); } 
    public function add($part) { return array_push($this->_parts, $part); }
}





/**
 * 建造者抽象類
 *
 */
abstract class Builder {
    public abstract function buildPart1();
    public abstract function buildPart2();
    public abstract function getResult();
}

/**
 * 
 * 具體建造者
 * 實現其具體方法
 */
class ConcreteBuilder extends Builder {  
    private $_product;
    public function __construct() { $this->_product = new Product(); }
    public function buildPart1() { $this->_product->add("Part1"); } 
    public function buildPart2() { $this->_product->add("Part2"); }
    public function getResult() { return $this->_product; }
}
 /**
  * 
  *導演者
  */
class Director { 
    public function __construct(Builder $builder) {
        $builder->buildPart1();//導演指揮具體建造者生產產品
        $builder->buildPart2();
    }
}




// client 
$buidler = new ConcreteBuilder();
$director = new Director($buidler);
$product = $buidler->getResult();
echo "<pre>";
var_dump($product);
echo "</pre>";
/*輸出: object(Product)#2 (1) {
["_parts":"Product":private]=>
array(2) {
    [0]=>string(5) "Part1"
    [1]=>string(5) "Part2"
}
} */
?>

5. Prototype(原型模式)

有時候,部分物件需要被初始化多次。而特別是在如果初始化需要耗費大量時間與資源的時候進行預初始化並且儲存下這些物件,就會用到原型模式:

<?php
/**
 * 
 * 原型介面
 *
 */
interface Prototype { public function copy(); }

/**
 * 具體實現
 *
 */
class ConcretePrototype implements Prototype{
    private  $_name;
    public function __construct($name) { $this->_name = $name; } 
    public function copy() { return clone $this;}
}

class Test {}

// client
$object1 = new ConcretePrototype(new Test());
var_dump($object1);//輸出:object(ConcretePrototype)#1 (1) { ["_name":"ConcretePrototype":private]=> object(Test)#2 (0) { } } 
$object2 = $object1->copy();
var_dump($object2);//輸出:object(ConcretePrototype)#3 (1) { ["_name":"ConcretePrototype":private]=> object(Test)#2 (0) { } }
?>

Structural Patterns(結構設計模式)

6. Adapter(介面卡模式)

這種模式允許使用不同的介面重構某個類,可以允許使用不同的呼叫方式進行呼叫:

<?php
/**
 * 第一種方式:物件介面卡
 */
interface Target {
    public function sampleMethod1();
    public function sampleMethod2();
}

class Adaptee {
    public function sampleMethod1() {
        echo '++++++++';
    }
}

class Adapter implements Target {
    private $_adaptee;

    public function __construct(Adaptee $adaptee) {
        $this->_adaptee = $adaptee;
    }

    public function sampleMethod1() {
        $this->_adaptee->sampleMethod1(); 
    }

    public function sampleMethod2() {
        echo '————————'; 
    }
}
$adapter = new Adapter(new Adaptee());
$adapter->sampleMethod1();//輸出:++++++++
$adapter->sampleMethod2();//輸出:————————



/**
 * 第二種方式:類介面卡
 */
interface Target2 {
    public function sampleMethod1();
    public function sampleMethod2();
}

class Adaptee2 { // 源角色
    public function sampleMethod1() {echo '++++++++';}
}

class Adapter2 extends Adaptee2 implements Target2 { // 適配后角色
    public function sampleMethod2() {echo '————————';} 
}

$adapter = new Adapter2();
$adapter->sampleMethod1();//輸出:++++++++
$adapter->sampleMethod2();//輸出:————————
?>

7. Bridge(橋接模式)

將抽象部分與它的實現部分分離,使他們都可以獨立的變抽象與它的實現分離,即抽象類和它的派生類用來實現自己的物件

橋接與介面卡模式的關係(介面卡模式上面已講解):
橋接屬於聚合關係,兩者關聯 但不繼承
介面卡屬於組合關係,適配者需要繼承源

聚合關係:A物件可以包含B物件 但B物件不是A物件的一部分

<?php
/**
 * 
 *實現化角色, 給出實現化角色的介面,但不給出具體的實現。
 */
abstract class Implementor { 
    abstract public function operationImp();
}

class ConcreteImplementorA extends Implementor { // 具體化角色A
    public function operationImp() {echo "A";}
}

class ConcreteImplementorB extends Implementor { // 具體化角色B
    public function operationImp() {echo "B";}
}


/**
 * 
 * 抽象化角色,抽象化給出的定義,並儲存一個對實現化物件的引用
 */
abstract class Abstraction { 
    protected $imp; // 對實現化物件的引用
    public function operation() {
        $this->imp->operationImp();
    }
}
class RefinedAbstraction extends Abstraction { // 修正抽象化角色, 擴充套件抽象化角色,改變和修正父類對抽象化的定義。
    public function __construct(Implementor $imp) {
        $this->imp = $imp;
    }
    public function operation() { $this->imp->operationImp(); }
}





// client
$abstraction = new RefinedAbstraction(new ConcreteImplementorA());
$abstraction->operation();//輸出:A
$abstraction = new RefinedAbstraction(new ConcreteImplementorB());
$abstraction->operation();//輸出:B
?>

8. Composite(合成模式)

組合模式(Composite Pattern)有時候又叫做部分-整體模式,用於將物件組合成樹形結構以表示“部分-整體”的層次關係。組合模式使得使用者對單個物件和組合物件的使用具有一致性。

常見使用場景:如樹形選單、資料夾選單、部門組織架構圖等。

<?php
/**
 * 
 *安全式合成模式
 */
interface Component {
    public function getComposite(); //返回自己的例項
    public function operation();
}

class Composite implements Component { // 樹枝元件角色
    private $_composites;
    public function __construct() { $this->_composites = array(); }
    public function getComposite() { return $this; }
     public function operation() {
         foreach ($this->_composites as $composite) {
            $composite->operation();
        }
     }

    public function add(Component $component) {  //聚集管理方法 新增一個子物件
        $this->_composites[] = $component;
    }

    public function remove(Component $component) { // 聚集管理方法 刪除一個子物件
        foreach ($this->_composites as $key => $row) {
            if ($component == $row) { unset($this->_composites[$key]); return TRUE; }
        } 
        return FALSE;
    }

    public function getChild() { // 聚集管理方法 返回所有的子物件
       return $this->_composites;
    }

}

class Leaf implements Component {
    private $_name; 
    public function __construct($name) { $this->_name = $name; }
    public function operation() {}
    public function getComposite() {return null;}
}

// client
$leaf1 = new Leaf('first');
$leaf2 = new Leaf('second');

$composite = new Composite();
$composite->add($leaf1);
$composite->add($leaf2);
$composite->operation();

$composite->remove($leaf2);
$composite->operation();






/**
 * 
 *透明式合成模式
 */
interface Component { // 抽象元件角色
    public function getComposite(); // 返回自己的例項
    public function operation(); // 示例方法
    public function add(Component $component); // 聚集管理方法,新增一個子物件
    public function remove(Component $component); // 聚集管理方法 刪除一個子物件
    public function getChild(); // 聚集管理方法 返回所有的子物件
}

class Composite implements Component { // 樹枝元件角色
    private $_composites;
    public function __construct() { $this->_composites = array(); } 
    public function getComposite() { return $this; }
    public function operation() { // 示例方法,呼叫各個子物件的operation方法
        foreach ($this->_composites as $composite) {
            $composite->operation();
        }
    }
    public function add(Component $component) { // 聚集管理方法 新增一個子物件
        $this->_composites[] = $component;
    }
    public function remove(Component $component) { // 聚集管理方法 刪除一個子物件
        foreach ($this->_composites as $key => $row) {
            if ($component == $row) { unset($this->_composites[$key]); return TRUE; }
        } 
        return FALSE;
    }
    public function getChild() { // 聚集管理方法 返回所有的子物件
       return $this->_composites;
    }

}

class Leaf implements Component {
    private $_name;
    public function __construct($name) {$this->_name = $name;}
    public function operation() {echo $this->_name."<br>";}
    public function getComposite() { return null; }
    public function add(Component $component) { return FALSE; }
    public function remove(Component $component) { return FALSE; }
    public function getChild() { return null; }
}

// client 
$leaf1 = new Leaf('first');
$leaf2 = new Leaf('second');

$composite = new Composite();
$composite->add($leaf1);
$composite->add($leaf2);
$composite->operation();

$composite->remove($leaf2);
$composite->operation();

?>

9. Decorator(裝飾器模式)

裝飾器模式允許我們根據執行時不同的情景動態地為某個物件呼叫前後新增不同的行

<?php
interface Component {
    public function operation();
}

abstract class Decorator implements Component{ // 裝飾角色 
    protected  $_component;
    public function __construct(Component $component) {
        $this->_component = $component;
    }
    public function operation() {
        $this->_component->operation();
    }
}

class ConcreteDecoratorA extends Decorator { // 具體裝飾類A
    public function __construct(Component $component) {
        parent::__construct($component);
    } 
    public function operation() {
        parent::operation();    //  呼叫裝飾類的操作
        $this->addedOperationA();   //  新增加的操作
    }
    public function addedOperationA() {echo 'A加點醬油;';}
}

class ConcreteDecoratorB extends Decorator { // 具體裝飾類B
    public function __construct(Component $component) {
        parent::__construct($component);
    } 
    public function operation() {
        parent::operation();
        $this->addedOperationB();
    }
    public function addedOperationB() {echo "B加點辣椒;";}
}

class ConcreteComponent implements Component{ //具體元件類
    public function operation() {} 
}

// clients
$component = new ConcreteComponent();
$decoratorA = new ConcreteDecoratorA($component);
$decoratorB = new ConcreteDecoratorB($decoratorA);

$decoratorA->operation();//輸出:A加點醬油;
echo '<br>--------<br>';
$decoratorB->operation();//輸出:A加點醬油;B加點辣椒;
?>

10. Facade(門面模式)

門面模式 (Facade)又稱外觀模式,用於為子系統中的一組介面提供一個一致的介面。門面模式定義了一個高層介面,這個介面使得子系統更加容易使用:引入門面角色之後,使用者只需要直接與門面角色互動,使用者與子系統之間的複雜關係由門面角色來實現,從而降低了系統的耦

<?php
class Camera {
    public function turnOn() {}
    public function turnOff() {}
    public function rotate($degrees) {}
}

class Light {
    public function turnOn() {}
    public function turnOff() {}
    public function changeBulb() {}
}

class Sensor {
    public function activate() {}
    public function deactivate() {}
    public function trigger() {}
}

class Alarm {
    public function activate() {}
    public function deactivate() {}
    public function ring() {}
    public function stopRing() {}
}

class SecurityFacade {
    private $_camera1, $_camera2;
    private $_light1, $_light2, $_light3;
    private $_sensor;
    private $_alarm;

    public function __construct() {
        $this->_camera1 = new Camera();
        $this->_camera2 = new Camera();

        $this->_light1 = new Light();
        $this->_light2 = new Light();
        $this->_light3 = new Light();

        $this->_sensor = new Sensor();
        $this->_alarm = new Alarm();
    }

    public function activate() {
        $this->_camera1->turnOn();
        $this->_camera2->turnOn();

        $this->_light1->turnOn();
        $this->_light2->turnOn();
        $this->_light3->turnOn();

        $this->_sensor->activate();
        $this->_alarm->activate();
    }

    public  function deactivate() {
        $this->_camera1->turnOff();
        $this->_camera2->turnOff();

        $this->_light1->turnOff();
        $this->_light2->turnOff();
        $this->_light3->turnOff();

        $this->_sensor->deactivate();
        $this->_alarm->deactivate();
    }
}


//client 
$security = new SecurityFacade();
$security->activate();
?> 

11. Proxy(代理模式)

代理模式(Proxy)為其他物件提供一種代理以控制對這個物件的訪問。使用代理模式建立代理物件,讓代理物件控制目標物件的訪問(目標物件可以是遠端的物件、建立開銷大的物件或需要安全控制的物件),並且可以在不改變目標物件的情況下新增一些額外的功能。

在某些情況下,一個客戶不想或者不能直接引用另一個物件,而代理物件可以在客戶端和目標物件之間起到中介的作用,並且可以通過代理物件去掉客戶不能看到的內容和服務或者新增客戶需要的額外服務。

經典例子就是網路代理,你想訪問 Facebook 或者 Twitter ,如何繞過 GFW?找個代理

<?
abstract class Subject { // 抽象主題角色
    abstract public function action();
}

class RealSubject extends Subject { // 真實主題角色
    public function __construct() {}
    public function action() {}
}

class ProxySubject extends Subject { // 代理主題角色
    private $_real_subject = NULL;
    public function __construct() {}

    public function action() {
        $this->_beforeAction();
        if (is_null($this->_real_subject)) {
            $this->_real_subject = new RealSubject();
        }
        $this->_real_subject->action();
        $this->_afterAction();
    }

    private function _beforeAction() {
        echo '在action前,我想幹點啥....';
    }

    private function _afterAction() {
         echo '在action後,我還想幹點啥....';
    }
}

// client
$subject = new ProxySubject();
$subject->action();//輸出:在action前,我想幹點啥....在action後,我還想幹點啥....
?> 

12. Flyweight(享元模式)

運用共享技術有效的支援大量細粒度的物件

享元模式變化的是物件的儲存開銷

享元模式中主要角色:

抽象享元(Flyweight)角色:此角色是所有的具體享元類的超類,為這些類規定出需要實現的公共介面。那些需要外運狀態的操作可以通過呼叫商業以引數形式傳入

具體享元(ConcreteFlyweight)角色:實現Flyweight介面,併為內部狀態(如果有的話)拉回儲存空間。ConcreteFlyweight物件必須是可共享的。它所儲存的狀態必須是內部的

不共享的具體享元(UnsharedConcreteFlyweight)角色:並非所有的Flyweight子類都需要被共享。Flyweigth使共享成為可能,但它並不強制共享

享元工廠(FlyweightFactory)角色:負責建立和管理享元角色。本角色必須保證享元物件可能被系統適當地共享

客戶端(Client)角色:本角色需要維護一個對所有享元物件的引用。本角色需要自行儲存所有享元物件的外部狀態

享元模式的優點:

Flyweight模式可以大幅度地降低記憶體中物件的數量

享元模式的缺點:

Flyweight模式使得系統更加複雜

Flyweight模式將享元物件的狀態外部化,而讀取外部狀態使得執行時間稍微變長

享元模式適用場景:

當一下情況成立時使用Flyweight模式:

1 一個應用程式使用了大量的物件

2 完全由於使用大量的物件,造成很大的儲存開銷

3 物件的大多數狀態都可變為外部狀態

4 如果刪除物件的外部狀態,那麼可以用相對較少的共享物件取代很多組物件

5 應用程式不依賴於物件標識

<?php
abstract class Resources{
    public $resource=null;

    abstract public function operate();
}

class unShareFlyWeight extends Resources{
    public function __construct($resource_str) {
        $this->resource = $resource_str;
    }

    public function operate(){
        echo $this->resource."<br>";
    }
}

class shareFlyWeight extends Resources{
    private $resources = array();

    public function get_resource($resource_str){
        if(isset($this->resources[$resource_str])) {
            return $this->resources[$resource_str];
        }else {
            return $this->resources[$resource_str] = $resource_str;
        }
    }

    public function operate(){
        foreach ($this->resources as $key => $resources) {
            echo $key.":".$resources."<br>";
        }
    }
}


// client
$flyweight = new shareFlyWeight();
$flyweight->get_resource('a');
$flyweight->operate();


$flyweight->get_resource('b');
$flyweight->operate();

$flyweight->get_resource('c');
$flyweight->operate();

// 不共享的物件,單獨呼叫
$uflyweight = new unShareFlyWeight('A');
$uflyweight->operate();

$uflyweight = new unShareFlyWeight('B');
$uflyweight->operate();
/* 輸出:
 a:a
 a:a
 b:b
 a:a
 b:b
 c:c
 A
 B */

Behavioral Patterns(行為模式)

13. Strategy(策略模式)

策略模式主要為了讓客戶類能夠更好地使用某些演算法而不需要知道其具體的實現。

<?php
interface Strategy { // 抽象策略角色,以介面實現
    public function do_method(); // 演算法介面
}

class ConcreteStrategyA implements Strategy { // 具體策略角色A 
    public function do_method() {
        echo 'do method A';
    }
}

class ConcreteStrategyB implements Strategy { // 具體策略角色B 
    public function do_method() {
        echo 'do method B';
    }
}

class ConcreteStrategyC implements Strategy { // 具體策略角色C
    public function do_method() {
        echo 'do method C';
    }
}


class Question{ // 環境角色
    private $_strategy;

    public function __construct(Strategy $strategy) {
        $this->_strategy = $strategy;
    } 
    public function handle_question() {
        $this->_strategy->do_method();
    }
}

// client
$strategyA = new ConcreteStrategyA();
$question = new Question($strategyA);
$question->handle_question();//輸出do method A

$strategyB = new ConcreteStrategyB();
$question = new Question($strategyB);
$question->handle_question();//輸出do method B

$strategyC = new ConcreteStrategyC();
$question = new Question($strategyC);
$question->handle_question();//輸出do method C
?>

14. TemplateMethod(模板方法模式)

模板模式準備一個抽象類,將部分邏輯以具體方法以及具體構造形式實現,然後宣告一些抽象方法來迫使子類實現剩餘的邏輯。不同的子類可以以不同的方式實現這些抽象方法,從而對剩餘的邏輯有不同的實現。先制定一個頂級邏輯框架,而將邏輯的細節留給具體的子類去實現。

<?php
abstract class AbstractClass { // 抽象模板角色
    public function templateMethod() { // 模板方法 呼叫基本方法組裝頂層邏輯
        $this->primitiveOperation1();
        $this->primitiveOperation2();
    }
    abstract protected function primitiveOperation1(); // 基本方法
    abstract protected function primitiveOperation2();
}

class ConcreteClass extends AbstractClass { // 具體模板角色
    protected function primitiveOperation1() {}
    protected function primitiveOperation2(){}

}

$class = new ConcreteClass();
$class->templateMethod();
?>

15. Observer(觀察者模式)

某個物件可以被設定為是可觀察的,只要通過某種方式允許其他物件註冊為觀察者。每當被觀察的物件改變時,會發送資訊給觀察者。

<?php

    interface IObserver{
        function onSendMsg( $sender, $args );
        function getName();
    }

    interface IObservable{
        function addObserver( $observer );
    }

    class UserList implements IObservable{
        private $_observers = array();

        public function sendMsg( $name ){
            foreach( $this->_observers as $obs ){
                $obs->onSendMsg( $this, $name );
            }
        }

        public function addObserver( $observer ){
            $this->_observers[]= $observer;
        }

        public function removeObserver($observer_name) {
            foreach($this->_observers as $index => $observer) {
                if ($observer->getName() === $observer_name) {
                    array_splice($this->_observers, $index, 1);
                    return;
                }
            }
        }
    }

    class UserListLogger implements IObserver{
        public function onSendMsg( $sender, $args ){
            echo( "'$args' send to UserListLogger\n" );
        }

        public function getName(){
            return 'UserListLogger';
        }
    }

    class OtherObserver implements IObserver{
        public function onSendMsg( $sender, $args ){
            echo( "'$args' send to OtherObserver\n" );
        }

        public function getName(){
            return 'OtherObserver';
        }
    }


    $ul = new UserList();//被觀察者
    $ul->addObserver( new UserListLogger() );//增加觀察者
    $ul->addObserver( new OtherObserver() );//增加觀察者
    $ul->sendMsg( "Jack" );//傳送訊息到觀察者

    $ul->removeObserver('UserListLogger');//移除觀察者
    $ul->sendMsg("hello");//傳送訊息到觀察者

 /*    輸出:'Jack' send to UserListLogger 'Jack' send to OtherObserver 'hello' send to OtherObserver */
?>

16. Iterator(迭代器模式)

迭代器模式 (Iterator),又叫做遊標(Cursor)模式。提供一種方法訪問一個容器(Container)物件中各個元素,而又不需暴露該物件的內部細節。

當你需要訪問一個聚合物件,而且不管這些物件是什麼都需要遍歷的時候,就應該考慮使用迭代器模式。另外,當需要對聚集有多種方式遍歷時,可以考慮去使用迭代器模式。迭代器模式為遍歷不同的聚集結構提供如開始、下一個、是否結束、當前哪一項等統一的介面。

php標準庫(SPL)中提供了迭代器介面 Iterator,要實現迭代器模式,實現該介面即可。

<?php
class sample implements Iterator {
    private $_items ;

    public function __construct(&$data) {
        $this->_items = $data;
    }
    public function current() {
        return current($this->_items);
    }

    public function next() {
        next($this->_items);   
    }

    public function key() {
        return key($this->_items);
    }

    public function rewind() {
        reset($this->_items);
    }

    public function valid() {                                                                              
        return ($this->current() !== FALSE);
    }
}

// client
$data = array(1, 2, 3, 4, 5);
$sa = new sample($data);
foreach ($sa AS $key => $row) {
    echo $key, ' ', $row, '<br />';
}
/* 輸出:
0 1
1 2
2 3
3 4
4 5 */

//Yii FrameWork Demo
class CMapIterator implements Iterator {
/**
* @var array the data to be iterated through
*/
    private $_d;
/**
* @var array list of keys in the map
*/
    private $_keys;
/**
* @var mixed current key
*/
    private $_key;

/**
* Constructor.
* @param array the data to be iterated through
*/
    public function __construct(&$data) {
        $this->_d=&$data;
        $this->_keys=array_keys($data);
    }

/**
* Rewinds internal array pointer.
* This method is required by the interface Iterator.
*/
    public function rewind() {                                                                                 
        $this->_key=reset($this->_keys);
    }

/**
* Returns the key of the current array element.
* This method is required by the interface Iterator.
* @return mixed the key of the current array element
*/
    public function key() {
        return $this->_key;
    }

/**
* Returns the current array element.
* This method is required by the interface Iterator.
* @return mixed the current array element
*/
    public function current() {
        return $this->_d[$this->_key];
    }

/**
* Moves the internal pointer to the next array element.
* This method is required by the interface Iterator.
*/
    public function next() {
        $this->_key=next($this->_keys);
    }

/**
* Returns whether there is an element at current position.
* This method is required by the interface Iterator.
* @return boolean
*/
    public function valid() {
        return $this->_key!==false;
    }
}

$data = array('s1' => 11, 's2' => 22, 's3' => 33);
$it = new CMapIterator($data);
foreach ($it as $row) {
    echo $row, '<br />';
}

/* 輸出:
11
22
33 */
?>

17. ResponsibilityChain(責任鏈模式)

這種模式有另一種稱呼:控制鏈模式。它主要由一系列對於某些命令的處理器構成,每個查詢會在處理器構成的責任鏈中傳遞,在每個交匯點由處理器判斷是否需要對它們進行響應與處理。每次的處理程式會在有處理器處理這些請求時暫停。

<?php

abstract class Responsibility { // 抽象責任角色
    protected $next; // 下一個責任角色

    public function setNext(Responsibility $l) {
        $this->next = $l;
        return $this;
    }
    abstract public function operate(); // 操作方法
}

class ResponsibilityA extends Responsibility {
    public function __construct() {}
    public function operate(){
        if (false == is_null($this->next)) {
            $this->next->operate();
            echo 'Res_A start'."<br>";
        }
    }
}

class ResponsibilityB extends Responsibility {
    public function __construct() {}
    public function operate(){
        if (false == is_null($this->next)) {
            $this->next->operate();
            echo 'Res_B start';
        }
    }
}

$res_a = new ResponsibilityA();
$res_b = new ResponsibilityB();
$res_a->setNext($res_b);
$res_a->operate();//輸出:Res_A start
?>

18. Command(命令模式)

命令模式:在軟體系統中,“行為請求者”與“行為實現者”通常呈現一種“緊耦合”。但在某些場合,比如要對行為進行“記錄、撤銷/重做、事務”等處理,這種無法抵禦變化的緊耦合是不合適的。在這種情況下,如何將“行為請求者”與“行為實現者”解耦?將一組行為抽象為物件,實現二者之間的鬆耦合。這就是命令模式。
角色分析:
抽象命令:定義命令的介面,宣告執行的方法。
具體命令:命令介面實現物件,是“虛”的實現;通常會持有接收者,並呼叫接收者的功能來完成命令要執行的操作。
命令接收者:接收者,真正執行命令的物件。任何類都可能成為一個接收者,只要它能夠實現命令要求實現的相應功能。
控制者:要求命令物件執行請求,通常會持有命令物件,可以持有很多的命令物件。這個是客戶端真正觸發命令並要求命令執行相應操作的地方,也就是說相當於使用命令物件的入口。

      <?php
interface Command { // 命令角色
    public function execute(); // 執行方法
}

class ConcreteCommand implements Command { // 具體命令方法 
    private $_receiver; 
    public function __construct(Receiver $receiver) {
        $this->_receiver = $receiver;
    }
    public function execute() {
        $this->_receiver->action();
    }
}

class Receiver { // 接收者角色
    private $_name;
    public function __construct($name) {
        $this->_name = $name;
    }
    public function action() {
        echo 'receive some cmd:'.$this->_name;
    }
}

class Invoker { // 請求者角色
    private $_command; 
    public function __construct(Command $command) {
        $this->_command = $command;
    }
    public function action() {
        $this->_command->execute();
    }
}

$receiver = new Receiver('hello world');
$command = new ConcreteCommand($receiver);
$invoker = new Invoker($command);
$invoker->action();//輸出:receive some cmd:hello world
?>

備忘錄模式又叫做快照模式(Snapshot)或 Token 模式,備忘錄模式的用意是在不破壞封裝性的前提下,捕獲一個物件的內部狀態,並在該物件之外儲存這個狀態,這樣就可以在合適的時候將該物件恢復到原先儲存的狀態。

我們在程式設計的時候,經常需要儲存物件的中間狀態,當需要的時候,可以恢復到這個狀態。比如,我們使用Eclipse進行程式設計時,假如編寫失誤(例如不小心誤刪除了幾行程式碼),我們希望返回刪除前的狀態,便可以使用Ctrl+Z來進行返回。這時我們便可以使用備忘錄模式來實現。
UML:
這裡寫圖片描述
備忘錄模式所涉及的角色有三個:備忘錄(Memento)角色、發起人(Originator)角色、負責人(Caretaker)角色。

這三個角色的職責分別是:

發起人:記錄當前時刻的內部狀態,負責定義哪些屬於備份範圍的狀態,負責建立和恢復備忘錄資料。
備忘錄:負責儲存發起人物件的內部狀態,在需要的時候提供發起人需要的內部狀態。
管理角色:對備忘錄進行管理,儲存和提供備忘錄。

<?php

class Originator { // 發起人(Originator)角色
    private $_state;
    public function __construct() {
        $this->_state = '';
    }
    public function createMemento() { // 建立備忘錄
        return new Memento($this->_state);
    }
    public function restoreMemento(Memento $memento) { // 將發起人恢復到備忘錄物件記錄的狀態上
        $this->_state = $memento->getState();
    }
    public function setState($state) { $this->_state = $state; } 
    public function getState() { return $this->_state; }
    public function showState() {
        echo $this->_state;echo "<br>";
    }

}

class Memento { // 備忘錄(Memento)角色 
    private $_state;
    public function __construct($state) {
        $this->setState($state);
    }
    public function getState() { return $this->_state; } 
    public function setState($state) { $this->_state = $state;}
}

class Caretaker { // 負責人(Caretaker)角色 
    private $_memento;
    public function getMemento() { return $this->_memento; } 
    public function setMemento(Memento $memento) { $this->_memento = $memento; }
}

// client
/* 建立目標物件 */
$org = new Originator();
$org->setState('open');
$org->showState();

/* 建立備忘 */
$memento = $org->createMemento();

/* 通過Caretaker儲存此備忘 */
$caretaker = new Caretaker();
$caretaker->setMemento($memento);

/* 改變目標物件的狀態 */
$org->setState('close');
$org->showState();

$org->restoreMemento($memento);
$org->showState();

/* 改變目標物件的狀態 */
$org->setState('close');
$org->showState();

/* 還原操作 */
$org->restoreMemento($caretaker->getMemento());
$org->showState();
/* 輸出:
open
close
open
close
open */
?>

20. State(狀態模式)

狀態模式當一個物件的內在狀態改變時允許改變其行為,這個物件看起來像是改變了其類。狀態模式主要解決的是當控制一個物件狀態的條件表示式過於複雜時的情況。把狀態的判斷邏輯轉移到表示不同狀態的一系列類中,可以把複雜的判斷邏輯簡化。
UML類圖:
這裡寫圖片描述
角色:
上下文環境(Work):它定義了客戶程式需要的介面並維護一個具體狀態角色的例項,將與狀態相關的操作委託給當前的具體物件來處理。
抽象狀態(State):定義一個介面以封裝使用上下文環境的的一個特定狀態相關的行為。
具體狀態(AmState):實現抽象狀態定義的介面。

         <?php
interface State { // 抽象狀態角色
    public function handle(Context $context); // 方法示例
}

class ConcreteStateA implements State { // 具體狀態角色A
    private static $_instance = null;
    private function __construct() {}
    public static function getInstance() { // 靜態工廠方法,返還此類的唯一例項
        if (is_null(self::$_instance)) {
            self::$_instance = new ConcreteStateA();
        }
        return self::$_instance;
    }

    public function handle(Context $context) {
        echo 'concrete_a'."<br>";
        $context->setState(ConcreteStateB::getInstance());
    }

}

class ConcreteStateB implements State { // 具體狀態角色B
    private static $_instance = null;
    private function __construct() {}
    public static function getInstance() {
        if (is_null(self::$_instance)) {
            self::$_instance = new ConcreteStateB();
        }
        return self::$_instance;
    }

    public function handle(Context $context) {
        echo 'concrete_b'."<br>";
        $context->setState(ConcreteStateA::getInstance());
    }
}

class Context { // 環境角色 
    private $_state;
    public function __construct() { // 預設為stateA
        $this->_state = ConcreteStateA::getInstance();
    }
    public function setState(State $state) {
        $this->_state = $state;
    }
    public function request() {
        $this->_state->handle($this);
    }
}

// client
$context = new Context();
$context->request();
$context->request();
$context->request();
$context->request();
/* 輸出:
concrete_a
concrete_b
concrete_a
concrete_b */
?>

21. Visitor(訪問者模式)

訪問者模式是一種行為型模式,訪問者表示一個作用於某物件結構中各元素的操作。它可以在不修改各元素類的前提下定義作用於這些元素的新操作,即動態的增加具體訪問者角色。

訪問者模式利用了雙重分派。先將訪問者傳入元素物件的Accept方法中,然後元素物件再將自己傳入訪問者,之後訪問者執行元素的相應方法。

主要角色

抽象訪問者角色(Visitor):為該物件結構(ObjectStructure)中的每一個具體元素提供一個訪問操作介面。該操作介面的名字和引數標識了 要訪問的具體元素角色。這樣訪問者就可以通過該元素角色的特定介面直接訪問它。
具體訪問者角色(ConcreteVisitor):實現抽象訪問者角色介面中針對各個具體元素角色宣告的操作。
抽象節點(Node)角色:該介面定義一個accept操作接受具體的訪問者。
具體節點(Node)角色:實現抽象節點角色中的accept操作。
物件結構角色(ObjectStructure):這是使用訪問者模式必備的角色。它要具備以下特徵:能列舉它的元素;可以提供一個高層的介面以允許該訪問者訪問它的元素;可以是一個複合(組合模式)或是一個集合,如一個列表或一個無序集合(在PHP中我們使用陣列代替,因為PHP中的陣列本來就是一個可以放置任何型別資料的集合)
適用性

訪問者模式多用在聚集型別多樣的情況下。在普通的形式下必須判斷每個元素是屬於什麼型別然後進行相應的操作,從而誕生出冗長的條件轉移語句。而訪問者模式則可以比較好的解決這個問題。對每個元素統一呼叫element−>accept(vistor)即可。
訪問者模式多用於被訪問的類結構比較穩定的情況下,即不會隨便新增子類。訪問者模式允許被訪問結構新增新的方法。

<?php
interface Visitor { // 抽象訪問者角色
    public function visitConcreteElementA(ConcreteElementA $elementA);
    public function visitConcreteElementB(concreteElementB $elementB);
}

interface Element { // 抽象節點角色
    public function accept(Visitor $visitor);
}

class ConcreteVisitor1 implements Visitor { // 具體的訪問者1
    public function visitConcreteElementA(ConcreteElementA $elementA) {}
    public function visitConcreteElementB(ConcreteElementB $elementB) {}
}

class ConcreteVisitor2 implements Visitor { // 具體的訪問者2
    public function visitConcreteElementA(ConcreteElementA $elementA) {}
    public function visitConcreteElementB(ConcreteElementB $elementB) {}
}

class ConcreteElementA implements Element { // 具體元素A
    private $_name;
    public function __construct($name) { $this->_name = $name; } 
    public function getName() { return $this->_name; }
    public function accept(Visitor $visitor) { // 接受訪問者呼叫它針對該元素的新方法
        $visitor->visitConcreteElementA($this);
    }
}

class ConcreteElementB implements Element { // 具體元素B
    private $_name; 
    public function __construct($name) { $this->_name = $name;}
    public function getName() { return $this->_name; }
    public function accept(Visitor $visitor) { // 接受訪問者呼叫它針對該元素的新方法
        $visitor->visitConcreteElementB($this);
    }
}

class ObjectStructure { // 物件結構 即元素的集合
    private $_collection; 
    public function __construct() { $this->_collection = array(); } 
    public function attach(Element $element) {
        return array_push($this->_collection, $element);
    }
    public function detach(Element $element) {
        $index = array_search($element, $this->_collection);
        if ($index !== FALSE) {
            unset($this->_collection[$index]);
        }
        return $index;
    }
    public function accept(Visitor $visitor) {
        foreach ($this->_collection as $element) {
            $element->accept($visitor);
        }
    }
}

// client
$elementA = new ConcreteElementA("ElementA");
$elementB = new ConcreteElementB("ElementB");
$elementA2 = new ConcreteElementB("ElementA2");
$visitor1 = new ConcreteVisitor1();
$visitor2 = new ConcreteVisitor2();

$os = new ObjectStructure();
$os->attach($elementA);
$os->attach($elementB);
$os->attach($elementA2);
$os->detach($elementA);
$os->accept($visitor1);
$os->accept($visitor2);
?>

22. Mediator(中介者模式)

中介者模式用於開發一個物件,這個物件能夠在類似物件相互之間不直接相互的情況下傳送或者調解對這些物件的集合的修改。 一般處理具有類似屬性,需要保持同步的非耦合物件時,最佳的做法就是中介者模式。PHP中不是特別常用的設計模式。

<?php
abstract class Mediator { // 中介者角色
    abstract public function send($message,$colleague); 
} 

abstract class Colleague { // 抽象物件
    private $_mediator = null; 
    public function __construct($mediator) { 
        $this->_mediator = $mediator; 
    } 
    public function send($message) { 
        $this->_mediator->send($message,$this); 
    } 
    abstract public function notify($message); 
} 

class ConcreteMediator extends Mediator { // 具體中介者角色
    private $_colleague1 = null; 
    private $_colleague2 = null; 
    public function send($message,$colleague) {
        //echo $colleague->notify($message);
        if($colleague == $this->_colleague1) { 
            $this->_colleague1->notify($message); 
        } else { 
            $this->_colleague2->notify($message); 
        } 
    }
    public function set($colleague1,$colleague2) { 
        $this->_colleague1 = $colleague1; 
        $this->_colleague2 = $colleague2; 
    } 
} 

class Colleague1 extends Colleague { // 具體物件角色
    public function notify($message) {
        echo 'colleague1:'.$message."<br>";
    } 
} 

class Colleague2 extends Colleague { // 具體物件角色
    public function notify($message) { 
        echo 'colleague2:'.$message."<br>";
    } 
} 

// client
$objMediator = new ConcreteMediator(); 
$objC1 = new Colleague1($objMediator); 
$objC2 = new Colleague2($objMediator); 
$objMediator->set($objC1,$objC2); 
$objC1->send("to c2 from c1"); //輸出:colleague1:to c2 from c1
$objC2->send("to c1 from c2"); //輸出:colleague2:to c1 from c2
?> 

23. Interpreter(直譯器模式)

給定一個語言, 定義它的文法的一種表示,並定義一個直譯器,該直譯器使用該表示來解釋語言中的句子。
角色:
環境角色(PlayContent):定義解釋規則的全域性資訊。
抽象直譯器(Empress):定義了部分解釋具體實現,封裝了一些由具體直譯器實現的介面。
具體直譯器(MusicNote):實現抽象直譯器的介面,進行具體的解釋執行。

<?php
class Expression { //抽象表示
    function interpreter($str) { 
        return $str; 
    } 
} 

class ExpressionNum extends Expression { //表示數字
    function interpreter($str) { 
        switch($str) { 
            case "0": return "零"; 
            case "1": return "一"; 
            case "2": return "二"; 
            case "3": return "三"; 
            case "4": return "四"; 
            case "5": return "五"; 
            case "6": return "六"; 
            case "7": return "七"; 
            case "8": return "八"; 
            case "9": return "九"; 
        } 
    } 
} 

class ExpressionCharater extends Expression { //表示字元
    function interpreter($str) { 
        return strtoupper($str); 
    } 
} 

class Interpreter { //直譯器
    function execute($string) { 
        $expression = null; 
        for($i = 0;$i<strlen($string);$i++) { 
            $temp = $string[$i]; 
            switch(true) { 
                case is_numeric($temp): $expression = new ExpressionNum(); break; 
                default: $expression = new ExpressionCharater(); 
            } 
            echo $expression->interpreter($temp);
            echo "<br>"; 
        } 
    } 
} 

//client
$obj = new Interpreter(); 
$obj->execute("123s45abc"); 
/* 輸出:
一
二
三
S
四
五
A
B
C */
?>

相關推薦

Java中的24設計模式與7大原則

工廠模式 職責 需要 占位符 ati gre template 層次 cto 一、創建型模式 1、抽象工廠模式(Abstract factory pattern): 提供一個接口, 用於創建相關或依賴對象的家族, 而不需要指定具體類.2、生成器模式(Builder pat

23設計模式介紹以及單例模式的學習

單例模式 餓漢式 23種設計模式 gof23 1、GOF23 設計模式總共分成創建型模式、結構型模式和行為型模式三種: a、創建型模式: - 單例模式、工廠模式、抽象工廠模式、建造者模式、原型模式 b、構建型模式: - 適配器模式、橋接模式、裝配模式、組合模式、建造者模

23設計模式介紹(一)---- 創建型模式

接口 ret static 深復制 return 對象 相互 object c png 由於設計模式篇幅比較大,如果在一篇文章講完所有的設計模式的話不利於閱讀。於是我把它分為三篇文章 23種設計模式介紹(一)---- 創建型模式 23種設計模式介紹(二)---- 結構型模

【Unity與23設計模式】狀態模式(State)

unity public text 開始 sys 狀態模式 改變 val 繼承 定義: “讓一個對象的行為隨著內部狀態的改變而變化,而該對象也像是換了類一樣” 應用場景: 角色AI:控制角色在不同狀態下的AI行為 服務器連接狀態:開始連線、連線中、斷線等狀態 關卡進

轉:23設計模式的應用場景

橋模式 man 16px pop 表示 black strong art bstr 設計模式主要分三個類型:創建型、結構型和行為型。 其中創建型有: 一、Singleton,單例模式:保證一個類只有一個實例,並提供一個訪問它的全局訪問點 ;

【Unity3D與23設計模式】建造者模式(Builder)

產出 private 一個 gof 行為 並且 bstr reac 定義 GoF中定義: “將一個復雜的構建流程與它的對象表現分離出來,讓相同的構建流程可以產生不同的對象行為表現。” 建造者模式可以分為兩個步驟來實施: 1.將復雜的構建流程獨立出來,並將整個流程分成

23設計模式中的叠代器模式

pos over arr imp @override 一個 next() int position 叠代器模式:提供一種方法順序訪問一個聚合對象中的各個對象。 那麽如何提供一個方法順序呢? public interface Iterator<T>{   publ

23設計模式中的訪問者模式

功能需求 封裝 改變 擴展 數據結構 模式 困難 操作 如果 訪問者模式:對於一組對象,在不改變數據結構的前提下,增加作用於這些結構元素新的功能。 適用於數據結構相對穩定,它把數據結構和作用於其上的操作解耦,使得操作集合可以相對自由地演化。 優點: 符合單一職責原則 擴展性

23設計模式中的原型模式

1-1 ... 實例代碼 sets each png 為什麽 .get protect 原型模式:通過復制現有實例來創建新的實例,無須知道相應類的信息。 個人見解:在大量循環時,需要初始化對象,用 原型模式能節省大量的初始化所花費的時間,值得一談的是淺復制和深復制 淺復制:

java 23設計模式

代理 建造者 學習 article 適配器 htm ava arc 叠代 備註這是別人總結的本來想轉載可惜不會怎麽轉載(感謝) 以下是學習過程中查詢的資料,別人總結的資料,比較容易理解(站在各位巨人的肩膀上,望博主勿究) 創建型抽象工廠模式 http://www.cnblo

23設計模式之觀察者模式

主題 一個 server bsp 監聽 images 關系 .com 自動更新 觀察者模式(Observer):定義了一種一對多的關系,讓多個觀察者對象同時監聽某一個主題對象。這個主題對象在狀態發生變化時,會通知所有觀察者對象,使它們能夠自動更新自己。 23種設計模式之

23設計模式之抽象工廠模式

tor turn sql數據庫 png insert face sign 相關 reat 抽象工廠模式(Abstract Factory):提供一個創建一系列相關或相互依賴對象的接口,而無需指定它們具體的類。 package designMode.abstractFa

23設計模式之模板方法模式

技術分享 cnblogs ati strac void package com rim div 模板方法模式(TemplateMethod):定義一個操作中的算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以不改變一個算法的結構即可重定義該算法的某些特定步驟。

(35)23設計模式研究之六【命令模式

獨立 場景 處理 針對 客戶端 抽象 軟件 comm mman 命令模式 一:定義 將一個請求封裝為一個對象(即我們創建的Command對象),從而使你可用不同的請求對客戶進行參數化; 對請求排隊或記錄請求日誌,以及支持可撤銷的操作。 二:實現 解決的問題   在軟件系統

java常見的幾設計模式

設計模式 單例 餓漢式 懶漢式 設計模式 1、概述 1)設計模式(Design pattern):是一套被反復使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結; 2)分類: 創建型模式(創建對象的): 單例模式、抽象工廠模式、建造者模式、工廠模式、原型模式。 行為型模式(對象

23設計模式分類

以及 日誌 visitor 聚合 享元模式 不兼容 復雜 res ons 設計模式主要分三個類型:創建型、結構型和行為型。 其中創建型有: 一、Singleton,單例模式:保證一個類只有一個實例,並提供一個訪問它的全局訪問點 二、Abstract F

iOS 開發中的幾設計模式

設計模式 開發 模式 ios 設計 iOS 開發中的幾種設計模式

23設計模式--中介者模式-Mediator Pattern

ole 缺點 業務 -m ram -- 成了 ons 錯誤 一、中介者模式的介紹 中介者模式第一下想到的就是中介,房子中介,婚姻中介啊等等,當然筆者也希望來個婚姻中介給我介紹一個哈哈哈,,回歸正題中介者模式分成中介者類和用戶類,根據接口編程的方式我們再把中介和用戶類

23設計模式

{0} 項目 責任 lin git man next https com 一、責任鏈模式的介紹 責任鏈模式用簡單點的話來說,將責任一步一步傳下去,這就是責任,想到這個我們可以相當擊鼓傳花,這個是為了方便記憶,另外就是我們在項目中經常用到的審批流程等這一類的場

GoF23設計模式之行為型模式之訪問者模式

部分 strong 操作 定義 狀態 arraylist his tro 不同的 概述 表示一個作用於某對象結構中的各元素的操作。 它使你可以在不改變各元素的類的前提下定義作用於這些元素的新操作。 適用性 1.一個對象結構包含很多