1. 程式人生 > >慕課網----大話PHP設計模式 四(介面卡模式,資料物件對映模式,觀察者模式)

慕課網----大話PHP設計模式 四(介面卡模式,資料物件對映模式,觀察者模式)

12.介面卡模式
可以將截然不同的函式介面封裝成統一的API
實際應用舉例,php的資料庫操作有mysql,mysqli,pdo 3種,可以用介面卡模式統一成一致。類似的場景還有cache介面卡,將memcache,redis,file,apc等不同的快取函式,統一成一致。
實現方式,定義統一的介面,

//在一個檔案中,可以有一個類,也可以寫一個介面,這兩個可以寫在一個檔案裡面,然後生成幾個類去繼承這個介面
interface IDatabase{
    //host 資料的連線IP地址
    function connect($host, $user, $passwd, $dbname
)
;
function query($sql); function close(); }

然後在對應的檔案裡面繼承這個介面,然後按照各自的規則實現定義的這幾個類。
去建立對應的介面卡例項。
然後呼叫的時候,就看引入那個資料型別的檔案,就使用對應的方法。

//介面卡模式的封裝
$db = new Imooc\Database\Mysql();
$db->connect('127.0.0.1', 'root', 'root', 'test');
$db->query("show databases");
$db->close();

13.策略模式
將一組特定的行為和演算法封裝成類,以適應某些特定的上下文環境,這種模式就是策略模式。
實際:加入一個電商網站系統,針對男女性使用者要各自跳轉到不同的商品類目,並把所有廣告位展示不同的廣告。
正常的開發中,都是用if else來判斷男女載入不同的資訊。
實現Ioc,依賴倒置,控制反轉。

實現方式:
通過建立一個介面,把相應的方法定義出來,然後再建立對應的類來繼承這個介面。並實現這些方法。
然後再使用的時候,根據實際情況呼叫對應的策略。然後先呼叫set方法來設定策略生成的的東西,然後index函式來展示。

class Page{
    /**
     * @var \Imooc\UserStrategy
     */
    protected $strategy;
    function index(){
        echo "AD:";
        $this->strategy->showAd();
        echo "<br/>"
; echo "Category:"; $this->strategy->showCategory(); } function setStrategy(\Imooc\UserStrategy $strategy){ $this->strategy = $strategy; } } $page = new Page; if(isset($_GET['female'])){ $strategy = new \Imooc\FemaleUserStrategy(); }else{ $strategy = new \Imooc\MaleUserStrategy(); } $page->setStrategy($strategy); $page->index();

控制反轉:
可以很方便的替換兩個相關聯的類

14.資料物件對映模式
是將物件和資料儲存對映起來,對一個物件操作會對映為對資料儲存的操作。
在程式碼中實現資料物件對映模式,我們將實現一個ORM類,將複雜的SQL語句對映成物件屬性的操作。
結合使用資料物件對映模式,工廠模式,註冊模式。
這樣就可以遮蔽底層的資料操作。

這個就是yii的model實現資料庫操作的設計模式。

就是在控制器層不出現sql語句,然後再model裡面,__construct這個建構函式中建立資料庫連線,然後在__destruct解構函式中,將屬性儲存到資料庫裡面,使用sql的update操作。

15.觀察者模式
但一個物件發生改變時,依賴他的物件全部會受到通知,並自動更新
場景:一個事務發生後,會執行一連串更新操作。傳統的程式設計方式,就是在事件的程式碼之後直接加入處理邏輯,當更新的邏輯增多之後,程式碼會變得難以維護,這種方式是耦合的,侵入式的,增加新的邏輯需要修改事件主體的程式碼
觀察者模式實現了低耦合,非侵入式的通知與更新機制

抽象類,本身沒有任何程式碼,只有繼承了他的子類,才會有邏輯

實現的例子,首先定義一個Observer的介面

<?php

namespace Imooc;
interface Observer
{
    function update($event_info = null);
}

然後再定義一個EventGenerator的抽象類,Observer $observer這樣的引數實際上是要傳的就是一個Observer的物件,傳進來的必須是一個物件,如果沒有這個物件,可以直接new一個也行。然後就把所有的時間都儲存進來,然後更改了方法的話,就通過notify裡面,迴圈去通知所有的觀察者的物件,這樣就能實現低耦合了。

<?php
namespace Imooc;
abstract class EventGenerator
{
    private $obserbers = array();
    function addObserver(Observer $observer){
        $this->obserbers[] = $observer;
    }
    function notify(){
        foreach($this->obserbers as $obserber){
            $obserber->update();
        }
    }
}

在index檔案中測試的例子。寫了兩個觀察者的類,然後例項化觀察者介面中的update方法。然後加入觀察者後,通過event裡面去觸發。

//觀察者模式
class Event extends \Imooc\EventGenerator{
    function trigger(){
        echo "event";
        //update
        $this->notify();
    }
}

class Observer1 implements \Imooc\Observer{
    function update($event_info = null){
        echo "邏輯1";
    }
}

class Observer2 implements \Imooc\Observer{
    function update($event_info = null){
        echo "邏輯2";
    }
}

$event = new Event;
$event->addObserver(new Observer1);
$event->addObserver(new Observer2);
$event->trigger();