PHP常用設計模式,PHP常用設計模式詳解,PHP詳解設計模式,PHP設計模式

来源:https://www.cnblogs.com/death-satan/archive/2020/04/12/12683321.html
-Advertisement-
Play Games

PHP常用設計模式詳解 單例模式: php交流群:159789818 特性:單例類只能有一個實例 類內__construct構造函數私有化,防止new實例 類內__clone私有化,防止複製對象 設置一個$instance私有靜態屬性,為了保存當前類的實例 設置一個getInstance公有方法,為 ...


PHP常用設計模式詳解

 

單例模式:

php交流群:159789818

特性:單例類只能有一個實例

  1. 類內__construct構造函數私有化,防止new實例
  2. 類內__clone私有化,防止複製對象
  3. 設置一個$instance私有靜態屬性,為了保存當前類的實例
  4. 設置一個getInstance公有方法,為了獲取當前類的實例
  5. 減少new對象操作,合理使用記憶體

通常使用在獲取某個全局配置項,或者資料庫連接、操作等類上

Demo:

 1 <?php
 2 Class Demo{
 3 //用於保存當前類的實例
 4 private static $instance;
 5 //構造函數私有化,防止直接new當前對象
 6 private function __construct(){}
 7 //析構函數私有化,防止從外部直接複製當前對象
 8 private function __clone(){}
 9 //getInstance公有函數用於獲取當前類的實例
10 public static function getInstance()
11 {
12 //判斷當前類成員變數instance是否為空
13 //如果不為空,則直接返回類的實例
14 //如果為空,則new一個當前類的實例,並保存到類成員變數
15 //instance中,然後直接返回成員變數
16 if(empty(self::$instance))
17 {
18 //將實例保存到instance成員變數中
19 self::$instance = new static();
20 //直接返回成員變數
21 return self::$instance;
22 }else{
23 //直接返回類實例
24 return self::$instance;
25 }
26 }
27 }
28 $demo1 = Demo::getInstance();//獲取到實例
29 $demo2 = new Demo();//報錯

 

工廠模式(Factory Design Pattern)

特性:

  1. 降低系統耦合度
  2. 遵循開發-封閉原則 對修改封閉, 對擴展開放
  3. 通過工廠創建類的實例,而不是直接操作new關鍵字創建類的實例
  4. 已經使用的類內部發生改變,哪不需要在所有的地方都改變,只需要在類工廠類里改變既可
  5. 例如,支付寶微信銀行等對接就可以寫個工廠模式來對接

抽象工廠Demo:

<?php
//PaymentFactory.php
interface PaymentFactory
{
    //請求收款碼
    public function QRcode();
    //監聽收款
    public function Listen();
}
interface createPay { //將對象的創建抽象成一個介面
    function createOpen($class,$data);//內向創建
    function createIntro($class,$data);//外向創建
}
//微信支付類
Class WxPay implements PayMentFactory
{
    public function QRcode()
    {
        //微信業務邏輯代碼
        //返回收款碼以及訂單相關參數
        return "我是微信二維碼";
    }
    public function Listen()
    {
        //微信業務邏輯代碼
        //返回訂單結果
        return "正在監聽";
    }
}
//阿裡支付類
Class aliyun implements PayMentFactory
{
    public function QRcode()
    {
        //業務邏輯代碼
        //返回收款碼以及訂單相關參數
        return "我是支付寶二維碼";
    }
    public function Listen()
    {
        //業務邏輯代碼
        //返回訂單結果
        return "正在監聽";
    }
}
//實現createPay介面
class CreateP implements createPay
{
    public function createOpen($class,$data =[])
    {
        return new $class($data);
    }
    public function createIntro($class,$data = [])
    {
        return new $class($data);
    }
}
//開發者類
class Client{
    static function Get($class,$data = [])
    {
        $fac = new CreateP();
//        var_dump($fac);
        return $fac->createOpen($class,$data);
    }
}
$pay = Client::Get("WxPay");
echo $pay->QRcode(); //輸出,我是微信二維碼

 

註冊模式 Register

特性:

  1. 解決全局共用和交換對象
  2. 創建好的對象,掛到某個全局數組上
  3. 需要的時候直接去該數組上獲取即可
  4. 將對象實例註冊到全局樹上

Demo:

<?php
//全局註冊類
Class Register
{
    //存儲類的實例
    public static $maps;
    //註冊操作
    public static function Set($name,$cla)
    {
        //判斷是否已經存儲
    if(array_key_exists($name,self::$maps))
    {
        //如果全局maps內已有則直接返回
    return true;
    }else{
        //如果沒有name 則將實例和name按鍵值對存儲到成員變數內
        self::$maps[$name] = $cla;
        return true;
    }
   }
   //獲取類實例
   public static function Get($name)
   {
       //判斷name值是否存在
       if(array_key_exists($name,self::$maps))
       {
           //如果存在則直接返回對應的類的實例
           return self::$maps[$name];
       }else{
           //如果不存在,則返回false或者其他
           return false;
       }
   }
}

 

適配器模式 Adapter :

特性:

  1. 將各種不同的函數介面封裝到統一的api
  2. 降低因為介面底層代碼的不同,而導致的調用?(個人理解)

Demo(網上直接copy來的):

介面 IDatabase
<?php
namespace IMooc;
interface IDatabase
{
    function connect($host, $user, $passwd, $dbname);
    function query($sql);
    function close();
}
MySQL
<?php
namespace IMooc\Database;
use IMooc\IDatabase;
class MySQL implements IDatabase
{
    protected $conn;
    function connect($host, $user, $passwd, $dbname)
    {
        $conn = mysql_connect($host, $user, $passwd);
        mysql_select_db($dbname, $conn);
        $this->conn = $conn;
    }

    function query($sql)
    {
        $res = mysql_query($sql, $this->conn);
        return $res;
    }

    function close()
    {
        mysql_close($this->conn);
    }
}
MySQLi
<?php
namespace IMooc\Database;
use IMooc\IDatabase;
class MySQLi implements IDatabase
{
    protected $conn;

    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 IMooc\Database;
use IMooc\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);
    }
}

 

通過以上案例,PHP與MySQL的資料庫交互有三套API,在不同的場景下可能使用不同的API,那麼開發好的代碼,換一個環境,可能就要改變它的資料庫API,那麼就要改寫所有的代碼,使用適配器模式之後,就可以使用統一的API去屏蔽底層的API差異帶來的環境改變之後需要改寫代碼的問題

觀察者模式

特性:

  1. 觀察者模式(Observer),當一個對象狀態發生變化時,依賴它的對象全部會收到通知,並自動更新
  2. 一個事件發生後,要執行一連串更新操作。傳統的編程思想,就是在這個事件的代碼後直接加入處理的邏輯。當更新的邏輯增多之後,代碼會變得難以維護。這種方式是耦合的,侵入式的,增加新的邏輯需要修改事件的主體代碼。
  3. 觀察者模式實現了低耦合,非侵入式的通知與更新機制

Demo:

<?php
//EventGenerator
//事件觸發抽象類
abstract class EvemtGenerator
{
    //存儲觀察者類
    private $observer =[];
    //添加觀察者操作
    public function AddOb(Observer $observer)
    {
        $this->observer[] = $observer;
    }
    //觀察者通知操作
    public function notify()
    {
        //迴圈類成員變數,並執行對應的觀察者更新方法
        foreach ($this->observer as $observer)
        {
            //執行每個觀察者類內的更新操作
            $observer->update();
        }
    }
}
//定義觀察者介面
interface Observer
{
    public function update();
}

//實現一個被觀察者類
Class Test extends EvemtGenerator
{
    //實現一個登陸方法
    public function login()
    {
        return "登陸成功";
    }
}
//實現一個觀察者
Class Observer1 implements Observer
{
    //定義一個邏輯更新操作  例如:添加了csrf驗證
    public function update()
    {
       if($_POST['csrf'] == getCsrf())
       {
           return true;
       }else{
           exit("csrf驗證不正確");
       }
    }
}
//實例化Test類 被觀察
$event = new Test();
$event->AddOb(new Observer1());
$event->login();
//更新通知操作
$event->notify();

 

 

策略模式:

特性:

  1. 將一組特定的行為和演算法封裝成類,以適應某些特定的上下文環境
  2. 方便系統維護,例如:為每一個用戶登陸時展現不同的頁面
  3. 解耦

Demo:

//定義策略介面,規範策略行為
interface UserStrategy
{
    public function show();
    public function message();
}
//定義一個喜歡買西裝的用戶類
Class SuitUser implements UserStrategy
{
    public function show()
    {
        //為用戶跳轉到西裝頁面
        return "跳轉到西裝頁面";
    }
    public function message()
    {
        //發送message
        echo "即將為您展示最新的西裝某某某";
    }
}
//定義一個喜歡買裙子的用戶類
Class skirtUser implements UserStrategy
{
     public function show()
    {
        //為用戶跳轉到西裝頁面
        return "跳轉到裙子推薦頁面";
    }
    public function message()
    {
        //發送message
        echo "即將為您展示最新的裙子某某某";
    }
}
//定義一個業務類
Class Users
{
    //存儲對應的用戶類
    private $userCla;
    //執行策略介面
    public function Start()
    {
    echo "跳轉頁面是:".$this->strategy->show();
    echo "消息是:".$this->strategy->message();
    } 
    //註冊對應的用戶類
    public function SetStrategy(UserStrategy $strategy)
    {
        $this->$userCla = $strategy;
    }
}
//業務邏輯代碼 判斷用戶習性
$user1 = "西裝";
$user2 = "裙子";
$userL = new Users();
//如果用戶習性為喜歡看西裝或者買西裝則
if ($user1 == "西裝"){
$userL->SetStrategy(new SuitUser());
$userL->Start();
}

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 最近看到一個有意思的圖片,包含了鮮為人知的秘密。。。 先看看這張有意思的圖片。 圖左應該講的是基督教中的三位一體。翻譯成中文如下。 當然這不是我們的重點,我們的重點在右邊這個圖。講的是js中相等操作。 是js中的寬鬆相等(loose equals)。 是嚴格相等(strict equals)。 這兩 ...
  • thrift類似java裡面的socket和sockchannel中server和client通信 thrift最重要的是跨語言,裡面提供了序列化和反序列化、json和實體對象等方法 Apache Thrift軟體框架(用於可擴展的跨語言服務開發)將軟體堆棧與代碼生成引擎結合在一起,以構建可在C++ ...
  • 作為一個碼農,你知道如何啟動一個java線程嗎? 啟動線程 public class PrintThread extends Thread { public void run() { System.out.println("我是線程! 繼承自Thread"); } public static voi ...
  • 全民閱讀的時代已經來臨,目前使用讀書軟體的用戶數2.1億,日活躍用戶超過500萬,其中19-35歲年輕用戶占比超過60%,本科及以上學歷用戶占比高達80%,北上廣深及其他省會城市/直轄市用戶占比超過80%。**本人習慣使用微信讀書,為了方便整理書籍和導出筆記,便開發了這個小工具。** ...
  • 前言 在【JAVA進階架構師指南】系列二和三中,我們瞭解了JVM的記憶體模型以及類載入機制,其中在記憶體模型中,我們說到,從線程角度來說,JVM分為線程私有的區域(虛擬機棧/本地方法棧/程式計數器)和線程公有區域(方法區和java堆),其中線程私有區域記憶體隨著線程的結束而跟著被回收,GC主要關註的是堆和 ...
  • 靈魂拷問:在不重啟服務的前提下,如何讓配置修改生效的呢?有什麼奇技淫巧嗎? 靈魂拷問:在 Java 項目中,總能看到以 .properties 為尾碼的文件蹤影,這類配置文件是怎麼載入的呢? 項目研發過程中,總會遇到一些經常改變的參數,比如要連接的資料庫的連接地址、名稱、用戶名、密碼;再比如訪問三方 ...
  • 1、什麼是字元串? Go語言中字元串是一個位元組切片。把內容放在雙引號""之間,我們可以創建一個字元串,讓我們來看一下創建並列印字元串的簡單示例。 package main import ( "fmt" ) func main() { str := "hello golang" fmt.Println ...
  • 一、Java註解 1.引入起始:Java5.0開始引入; 2.該功能可用於類、構造方法、成員變數、方法、參數 3.註解功能的影響範圍:不影響程式的正常執行,但是會對編譯器等輔助工具產生影響。 4.定義:註解又可以稱為標註,是程式的元數據,也是程式代碼的標記。 5.獲取方式:在編譯、載入類和運行時。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...