學習筆記--php設計模式

設計模式簡介

網上有很多設計模式的介紹,也借鑒了很多。因此以下只是說自己對它的理解,若有錯誤之處,歡迎指出。設計模式是經過眾多編程實踐后,對面向對象編程總結的一些經驗,不同的設計模式有不同的優勢。但總的來說是為了重用代碼、讓代碼更容易被他人理解、保證代碼可靠性幾個方面。由此可見,在項目中采用設計模式思維去設計代碼很重要,合適的設計模式讓你的項目更加規范,嚴謹。

設計模式的類型

創建型模式

工廠模式(Factory Pattern)

抽象工廠模式(Abstract Factory Pattern)

單例模式(Singleton Pattern)

建造者模式(Builder Pattern)

原型模式(Prototype Pattern)

這些設計模式提供了一種在創建對象的同時隱藏創建邏輯的方式,而不是使用新的運算符直接實例化對象。這使得程序在判斷針對某個給定實例需要創建哪些對象時更加靈活。

結構型模式

適配器模式(Adapter Pattern)

橋接模式(Bridge Pattern)

過濾器模式(Filter、Criteria Pattern)

組合模式(Composite Pattern)

裝飾器模式(Decorator Pattern)

外觀模式(Facade Pattern)

享元模式(Flyweight Pattern)

代理模式(Proxy Pattern)

這些設計模式關注類和對象的組合。繼承的概念被用來組合接口和定義組合對象獲得新功能的方式

行為型模式

責任鏈模式(Chain of Responsibility Pattern)

命令模式(Command Pattern)

解釋器模式(Interpreter Pattern)

迭代器模式(Iterator Pattern)

中介者模式(Mediator Pattern)

備忘錄模式(Memento Pattern)

觀察者模式(Observer Pattern)

狀態模式(State Pattern)

空對象模式(Null Object Pattern)

策略模式(Strategy Pattern)

模板模式(Template Pattern)

訪問者模式(Visitor Pattern)

這些設計模式特別關注對象之間的通信。

常用設計模式總結

工廠模式

工廠模式是用工廠方法生成對象,而不是直接new一個對象。

假設我們在demo命名空間下有一個名叫Db的數據庫操作類,用普通的方法,如果我們想去創建一個Db的對象,我們會直接new一個出來。


$db = new demo\Db();

工廠模式就是用一個工廠方法替換掉直接new一個對象的操作,以后想創建對象就調用這個工廠方法。

<?php 
namespace demo;

class Factory{
    static public function createDb(){
        $db = new Db();
        return $db;
    }
}
$db=  demo\Factory::createDb();

工廠模式有什么好處呢, 我們的項目中多處都對Db類進行了new的操作,如果這個類發生了一些更改,比如說類名或者是參數的改變,沒用工廠模式的話我們就需要進行多處更改,而工廠模式只需要改這個工廠類就行了。很多其他設計模式也是依賴于工廠模式的。

單例模式

單例模式使某個類的對象僅能創建一次,通常一個項目中會多次用的Db這個數據庫連接類,如果在每個地方都調用工廠方法創建一個數據庫連接類,這樣是比較消耗資源的,我們只需要一個數據庫連接,單例模式就是來解決這個問題的。

我們打開Db類,首先把構造方法設置為私有的,這樣就禁止了在其他地方直接new我們的Db類

<?php 
namespace demo;

class Db{
    protected $db;
    private function __construct(){

    }
    static public function getInstance(){
        //條件判斷Db類是否已經new過
        if (self::$db) {
            return self::$db;
        } else {
            //構造方法被設置為了私有的,外部不能直接new,但自己內部可以new
            self::$db = new self();
            return self::$db;
        }
    }

//下面省略一系列操作數據庫的方法
}

Db類的構造方法設置為了私有的,那我們在工廠類中也不能直接new了,現在來修改我們的工廠類

<?php 
namespace demo;

class Factory{
    static public function createDb(){
        $db = Db::getInstance;
        return $db;
    }
}

現在不管我們調用多少次工廠方法,我們的數據庫連接都只會被創建一次。

注冊樹模式

注冊樹模式可以把我們的對象放在全局的樹上,讓對象可以全局共享

下面我們來編寫一個注冊樹的類,包含set,get,_unset三個操作。

<?php 
namespace demo;

class Register{
    protected static $objects;
    static public function set($alias,$object){
        self::$objedts[$alias] = $object;
    }

    static public function get($name){
        return self::$objedts[$name];
    }

    //unset是php中的關鍵詞,所以起名為_unset,移除對象
    static public function _unset($alias){
        unset(self::$objedts[$alias]);
    }
}

下面我們再把工廠方法改一下

<?php 
namespace demo;

class Factory{
    static public function createDb(){
        $db = Db::getInstance;
        //把單例模式生成的對象放在注冊樹上
        Register::set('db',$db);
    }
}

現在這個工廠方法只需要調用一次,以后再需要使用數據庫連接對象,直接從全局的注冊樹上拿就行了

 $db = Register::get("db");

至于這個工廠方法是么時候調用,可以在程序初始化的時候,我們的業務邏輯代碼只需要在注冊樹上把這個對象讀取出來即可。

適配器模式

適配器模式可以將截然不同的函數接口封裝成統一的API。例如,PHP的數據庫操作有mysql,mysqli,pdo 三種,可以用適配器模式統一成一致。類似的場景還有cache適配器,將memcache,redis,file,apc等不同的緩存函數,統一成一致。

下面還是以數據庫操作為例。
首先定義數據庫接口。

interface IDatabase
{
    function connect($host, $user, $passwd, $dbname);
    function query($sql); 
    function close();
}

接下來編寫不同的數據庫類,使它們變成一樣的接口。
這里主要講mysqli和pdo兩個

<?php
namespace demo\Database;

use demo\IDatabase;
class MySQLi implements IDatabase
{
    function connect($host, $user, $passwd, $dbname);
    {
        $conn = mysqli_connect($host, $user, $passwd, $dbname);
        $this->conn = $conn;
    }
    function query($sql)
    {
        return mysqli_query($this->conn,$sql);
    }
    function close()
    {
        mysqli_close($this->conn);
    }
}

下面是pdo

<?php
namespace demo\Database;

use demo\IDatabase;
class PDO implements IDatabase
{
      protected $conn;
    function connect($host, $user, $passwd, $dbname)
    {
         $conn = new \PDO("mysql:host=$host;dbname=$dbname",$user,$passwd);
         $this->conn = $conn;
    }
    function query($sql)
    {
        return $this->conn->query($sql);
    }
    function close()
    {
        unset($this->conn);
    }
}

外部調用

//通過改變實例化對象即可實現切換
//$db = new demo\Database\PDO();

$db = new demo\Database\MySQLi();
$db->connect('127.0.0.1','root','root','test');
$db->query("show databases");
$db->close();

策略模式

首先聲明一個策略的接口文件,它約定了策略有哪些行為。

<?php
interface UserStrategy {
    //約定了兩個方法
    function showAd();//顯示廣告
    function showCategory();//顯示一個類目
}

再來定義具體的策略文件
女性用戶

class FemaleUserStrategy implements UserStrategy {
    function showAd()
    {
        echo "熱門女裝";
    }
    function showCategory()
    {
        echo "女裝";
    }
}

男性用戶

class MaleUserStrategy implements UserStrategy {
    function showAd()
    {
        echo "熱門手機";
    }
    function showCategory()
    {
        echo "電子產品";
    }
}

頁面
class Page
{
protected $strategy;
function index()
{
echo "AD:";
$this->strategy->showAd();

    echo "Category";
    $this->strategy->showCategory();
}
function setStrategy(\demo\UserStrategy $strategy)
{
    $this->strategy = $strategy;
}

}
$page = new Page;
if (isset($_GET['female'])){
$strategy = new \demo\FemaleUserStrategy();
} else {
$strategy = new \demo\MaleUserStrategy();
}
$page->setStrategy($strategy);
$page->index();

——未完——

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,565評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,115評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,577評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,514評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,234評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,621評論 1 326
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,641評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,822評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,380評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,128評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,319評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,879評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,548評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,970評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,229評論 1 291
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,048評論 3 397
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,285評論 2 376

推薦閱讀更多精彩內容

  • 設計模式匯總 一、基礎知識 1. 設計模式概述 定義:設計模式(Design Pattern)是一套被反復使用、多...
    MinoyJet閱讀 3,960評論 1 15
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,814評論 18 139
  • 簡單工廠模式雖然簡單,但存在一個很嚴重的問題。當系統中需要引入新產品時,由于靜態工廠方法通過所傳入參數的不同來創建...
    justCode_閱讀 1,200評論 1 9
  • ** 創建型設計模式 **: 單例模式(Singleton Pattern) 工廠方法模式(Factor Patt...
    刀斧手何在閱讀 1,206評論 1 3
  • “富貴險中求”,這是廣為流傳的至理名言。大多數人只要聽到有投資機會,通常人們認為就是不看準時機也要冒把險,賭一把。...
    朱坤耀閱讀 186評論 0 2