16個PHP設計模式詳解

来源:http://www.cnblogs.com/shiyanlou/archive/2017/06/14/7009123.html
-Advertisement-
Play Games

說明:該教程全部截選自實驗樓教程 "【16個PHP設計模式詳解】" :主要介紹16個常用的設計模式的基礎概念和技術要點,通過UML類圖幫助理解設計模式中各個類之間的關聯關係,針對每種設計模式都使用PHP完成了一個代碼示例,讓你跟隨實例輕鬆入門設計模式。 一、工廠模式 工廠模式具體可分為三類模式:簡單 ...


說明:該教程全部截選自實驗樓教程【16個PHP設計模式詳解】:主要介紹16個常用的設計模式的基礎概念和技術要點,通過UML類圖幫助理解設計模式中各個類之間的關聯關係,針對每種設計模式都使用PHP完成了一個代碼示例,讓你跟隨實例輕鬆入門設計模式。

一、工廠模式

工廠模式具體可分為三類模式:簡單工廠模式,工廠方法模式,抽象工廠模式;

1.簡單工廠模式

又稱為靜態工廠方法(Static Factory Method)模式,它屬於類創建型模式。在簡單工廠模式中,可以根據參數的不同返回不同類的實例。簡單工廠模式專門定義一個類來負責創建其他類的實例,被創建的實例通常都具有共同的父類。

角色:

  • Factory類:負責創建具體產品的實例
  • Product類:抽象產品類,定義產品子類的公共介面
  • ConcreteProduct 類:具體產品類,實現Product父類的介面功能,也可添加自定義的功能

UML類圖:

此處輸入圖片的描述

示例代碼:

<?php 
//簡單工廠模式
class Cat
{
  function __construct()
  {
      echo "I am Cat class <br>";
  }
}
class Dog
{
  function __construct()
  {
      echo "I am Dog class <br>";
  }
}
class Factory
{
  public static function CreateAnimal($name){
      if ($name == 'cat') {
          return new Cat();
      } elseif ($name == 'dog') {
          return new Dog();
      }
  }
}

$cat = Factory::CreateAnimal('cat');
$dog = Factory::CreateAnimal('dog');

簡單工廠模式最大的優點在於實現對象的創建和對象的使用分離,將對象的創建交給專門的工廠類負責,但是其最大的缺點在於工廠類不夠靈活,增加新的具體產品需要修改工廠類的判斷邏輯代碼,而且產品較多時,工廠方法代碼將會非常複雜。

2.工廠方法模式

此模式中,通過定義一個抽象的核心工廠類,並定義創建產品對象的介面,創建具體產品實例的工作延遲到其工廠子類去完成。這樣做的好處是核心類只關註工廠類的介面定義,而具體的產品實例交給具體的工廠子類去創建。當系統需要新增一個產品是,無需修改現有系統代碼,只需要添加一個具體產品類和其對應的工廠子類,是系統的擴展性變得很好,符合面向對象編程的開閉原則;

角色:

  • Product:抽象產品類
  • ConcreteProduct:具體產品類
  • Factory:抽象工廠類
  • ConcreteFactory:具體工廠類

UML類圖:

此處輸入圖片的描述

示例代碼:

<?php 
interface Animal{
  public function run();
  public function say();
}
class Cat implements Animal
{
  public function run(){
      echo "I ran slowly <br>";
  }
  public function say(){
      echo "I am Cat class <br>";
  }
}
class Dog implements Animal
{
  public function run(){
      echo "I'm running fast <br>";
  }
  public function say(){
      echo "I am Dog class <br>";
  }
}
abstract class Factory{
  abstract static function createAnimal();
}
class CatFactory extends Factory
{
  public static function createAnimal()
  {
      return new Cat();
  }
}
class DogFactory extends Factory
{
  public static function createAnimal()
  {
      return new Dog();
  }
}

$cat = CatFactory::createAnimal();
$cat->say();
$cat->run();

$dog = DogFactory::createAnimal();
$dog->say();
$dog->run();

工廠方法模式是簡單工廠模式的進一步抽象和推廣。由於使用了面向對象的多態性,工廠方法模式保持了簡單工廠模式的優點,而且剋服了它的缺點。在工廠方法模式中,核心的工廠類不再負責所有產品的創建,而是將具體創建工作交給子類去做。這個核心類僅僅負責給出具體工廠必須實現的介面,而不負責產品類被實例化這種細節,這使得工廠方法模式可以允許系統在不修改工廠角色的情況下引進新產品。

3.抽象工廠模式

提供一個創建一系列相關或相互依賴對象的介面,而無須指定它們具體的類。抽象工廠模式又稱為Kit模式,屬於對象創建型模式。

此模式是對工廠方法模式的進一步擴展。在工廠方法模式中,一個具體的工廠負責生產一類具體的產品,即一對一的關係,但是,如果需要一個具體的工廠生產多種產品對象,那麼就需要用到抽象工廠模式了。

為了便於理解此模式,這裡介紹兩個概念:

  • 產品等級結構:產品等級結構即產品的繼承結構,如一個抽象類是電視機,其子類有海爾電視機、海信電視機、TCL電視機,則抽象電視機與具體品牌的電視機之間構成了一個產品等級結構,抽象電視機是父類,而具體品牌的電視機是其子類。
  • 產品族 :在抽象工廠模式中,產品族是指由同一個工廠生產的,位於不同產品等級結構中的一組產品,如海爾電器工廠生產的海爾電視機、海爾電冰箱,海爾電視機位於電視機產品等級結構中,海爾電冰箱位於電冰箱產品等級結構中。

角色:

  • 抽象工廠(AbstractFactory):擔任這個角色的是抽象工廠模式的核心,是與應用系統的商業邏輯無關的。
  • 具體工廠(Factory):這個角色直接在客戶端的調用下創建產品的實例,這個角色含有選擇合適的產品對象的邏輯,而這個邏輯是與應用系統商業邏輯緊密相關的。
  • 抽象產品(AbstractProduct):擔任這個角色的類是抽象工廠模式所創建的對象的父類,或它們共同擁有的介面
  • 具體產品(Product):抽象工廠模式所創建的任何產品對象都是一個具體的產品類的實例。

UML類圖:

此處輸入圖片的描述

示例代碼:

<?php 

interface TV{
  public function open();
  public function use();
}

class HaierTv implements TV
{
  public function open()
  {
      echo "Open Haier TV <br>";
  }

  public function use()
  {
      echo "I'm watching TV <br>";
  }
}

interface PC{
  public function work();
  public function play();
}

class LenovoPc implements PC
{
  public function work()
  {
      echo "I'm working on a Lenovo computer <br>";
  }
  public function play()
  {
      echo "Lenovo computers can be used to play games <br>";
  }
}

abstract class Factory{
  abstract public static function createPc();
  abstract public static function createTv();
}

class ProductFactory extends Factory
{
  public static function createTV()
  {
      return new HaierTv();
  }
  public static function createPc()
  {
      return new LenovoPc();
  }
}

$newTv = ProductFactory::createTV();
$newTv->open();
$newTv->use();

$newPc = ProductFactory::createPc();
$newPc->work();
$newPc->play();

二、建造者模式

又名:生成器模式,是一種對象構建模式。它可以將複雜對象的建造過程抽象出來(抽象類別),使這個抽象過程的不同實現方法可以構造出不同表現(屬性)的對象。

建造者模式是一步一步創建一個複雜的對象,它允許用戶只通過指定複雜對象的類型和內容就可以構建它們,用戶不需要知道內部的具體構建細節。例如,一輛汽車由輪子,發動機以及其他零件組成,對於普通人而言,我們使用的只是一輛完整的車,這時,我們需要加入一個構造者,讓他幫我們把這些組件按序組裝成為一輛完整的車。

角色:

  • Builder:抽象構造者類,為創建一個Product對象的各個部件指定抽象介面。
  • ConcreteBuilder:具體構造者類,實現Builder的介面以構造和裝配該產品的各個部件。定義並明確它所創建的表示。提供一個檢索產品的介面
  • Director:指揮者,構造一個使用Builder介面的對象。
  • Product:表示被構造的複雜對象。ConcreateBuilder創建該產品的內部表示並定義它的裝配過程。
    包含定義組成部件的類,包括將這些部件裝配成最終產品的介面。

UML類圖:

此處輸入圖片的描述

示例代碼:

<?php 
/**
* chouxiang builer
*/
abstract class Builder
{
  protected $car;
  abstract public function buildPartA();
  abstract public function buildPartB();
  abstract public function buildPartC();
  abstract public function getResult();
}

class CarBuilder extends Builder
{
  function __construct()
  {
      $this->car = new Car();
  }
  public function buildPartA(){
      $this->car->setPartA('發動機');
  }

  public function buildPartB(){
      $this->car->setPartB('輪子');
  }

  public function buildPartC(){
      $this->car->setPartC('其他零件');
  }

  public function getResult(){
      return $this->car;
  }
}

class Car
{
  protected $partA;
  protected $partB;
  protected $partC;

  public function setPartA($str){
      $this->partA = $str;
  }

  public function setPartB($str){
      $this->partB = $str;
  }

  public function setPartC($str){
      $this->partC = $str;
  }

  public function show()
  {
      echo "這輛車由:".$this->partA.','.$this->partB.',和'.$this->partC.'組成';
  }
}

class Director
{
  public $myBuilder;

  public function startBuild()
  {
      $this->myBuilder->buildPartA();
      $this->myBuilder->buildPartB();
      $this->myBuilder->buildPartC();
      return $this->myBuilder->getResult();
  }

  public function setBuilder(Builder $builder)
  {
      $this->myBuilder = $builder;
  }
}

$carBuilder = new CarBuilder();
$director = new Director();
$director->setBuilder($carBuilder);
$newCar = $director->startBuild();
$newCar->show();

三、單例模式

單例模式,也叫單子模式,是一種常用的軟體設計模式。在應用這個模式時,單例對象的必須保證只有一個實例存在。許多時候整個系統只需要擁有一個的全局對象,這樣有利於我們協調系統整體的行為。

實現單例模式的思路是:一個類能返回對象一個引用(永遠是同一個)和一個獲得該實例的方法(必須是靜態方法,通常使用getInstance這個名稱);當我們調用這個方法時,如果類持有的引用不為空就返回這個引用,如果類保持的引用為空就創建該類的實例並將實例的引用賦予該類保持的引用;同時我們還將該類的構造函數定義為私有方法,這樣其他處的代碼就無法通過調用該類的構造函數來實例化該類的對象,只有通過該類提供的靜態方法來得到該類的唯一實例。

---維基百科

單例模式的要點有:某個類只能有一個實例;它必須自行創建本身的實例;它必須自行向整個系統提供這個實例。單例模式是一種對象創建型模式。

角色:

  • Singleton:單例類

UML 類圖:

此處輸入圖片的描述

示例代碼:

<?php 

class Singleton
{
  private static $instance;
  //私有構造方法,禁止使用new創建對象
  private function __construct(){}

  public static function getInstance(){
      if (!isset(self::$instance)) {
          self::$instance = new self;
      }
      return self::$instance;
  }
  //將克隆方法設為私有,禁止克隆對象
  private function __clone(){}

  public function say()
  {
      echo "這是用單例模式創建對象實例 <br>";
  }
  public function operation()
  {
      echo "這裡可以添加其他方法和操作 <br>";
  }
}

// $shiyanlou = new Singleton();
$shiyanlou = Singleton::getInstance();
$shiyanlou->say();
$shiyanlou->operation();

$newShiyanlou = Singleton::getInstance();
var_dump($shiyanlou === $newShiyanlou);

上述的五個模式均屬於創建型模式,關於結構型模式,點擊【16個PHP設計模式詳解】即可查看了……


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

-Advertisement-
Play Games
更多相關文章
  • 一.建立資料庫 create database animal; create table animal( sno int, name varchar(20), weight varcahr(20), color varchar(20), birth date ); 插入數據 insert into ...
  • Python 跟 Python3 完全就是兩種語言   0x00 import caffe FAILED      環境為 Ubuntu 16 cuda 8.0 NVIDIA 361.77 Anaconda2。昨天莫名其妙Caffe不能用了: ...
  • 先看一下下麵的結果 解釋 int整型常量比較時,== 是值比較,所以1,2返回true。1,2是值比較。 new Integer() 每次構造一個新的Integer對象,所以3返回false。3是對象比較。 Integer.parseInt每次構造一個int常量,所以4返回true。4是值比較。 I ...
  • 因為工作的原因,學習停滯了很久,也落後了很多。真的,學習堅持很重要,我們身邊太多的誘惑,任何的困難都可能成為放棄的理由。讓自己一直在行走,哪怕步子再小,只要走,就有希望。送給自己,死磕到底。 集合 集合是一個無序的,不重覆的數據組合,它的主要作用如下: 去重,把一個列表變成集合,就自動去重了 關係測 ...
  • 一個對象占多少位元組? 關於對象的大小,對於C/C++來說,都是有sizeof函數可以直接獲取的,但是Java似乎沒有這樣的方法。不過還好,在JDK1.5之後引入了Instrumentation類,這個類提供了計算對象記憶體占用量的方法。至於具體Instrumentation類怎麼用就不說了,可以參看這 ...
  • 首先,來看下MAVENx項目標準的目錄結構: 一般情況下,我們用到的資源文件(各種xml,properites,xsd文件等)都放在src/main/resources下麵,利用maven打包時,maven能把這些資源文件打包到相應的jar或者war里。 有時候,比如mybatis的mapper.x ...
  • DOM4J解析 特征: 1、JDOM的一種智能分支,它合併了許多超出基本XML文檔表示的功能。 2、它使用介面和抽象基本類方法。 3、具有性能優異、靈活性好、功能強大和極端易用的特點。 4、是一個開放源碼的文件 jar包:dom4j-1.6.1.jar 創建 book.xml: 運行結果: 解析 b ...
  • 上面呢,是jsp頁面的代碼,因為是純插件測試,可以直接複製過去使用的, dao層就不用寫了吧,只是一個查詢,下麵我把ztree的表欄位附上 希望可以幫到大家,這就是我再學習ztree插件時的測試代碼,ssh框架註解版,在其他框架里還沒有試過,但是瞭解了使用方法,應該都沒問題,我相信你們都比我強的多。 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...