PHP設計模式學習下

attachments-2020-08-8oEXw5tv5f4cafab8d183.png

單例模式理解:

  • 使某個類的對象只被建立一次。
  • 單例模式的最大好處就是減小資源的浪費,保證整個環境中只存在一個實例化的對象,特別適合資源鏈接類的編寫。
  • 單例模式的意思就是隻建立一個資源(對象,數據庫連接等),說白了,本質就是防止外部實例化類+判斷是否存在來返回或建立後返回對象。
// 單例模式(口訣:三私一公)
class Singleton{
  //私有化構造方法,禁止外部實例化對象
  private function __construct(){}
 //私有化__clone,防止對象被克隆
  private function __clone(){}
 //私有化內部實例化的對象
  private static $instance = null;
 // 公有靜態實例方法
  public static function getInstance(){
    if(self::$instance == null){
      //內部實例化對象
      self::$instance = new self();
    }
     return self::$instance;
   }
}

工廠模式理解:

  • 工廠方法或者類生成對象,而不是在代碼中直接new。
  • 咱們定義一個專門用來建立其它對象的類。 這樣在須要調用某個類的時候,咱們就不須要去使用new關鍵字實例化這個類,而是經過咱們的工廠類調用某個方法獲得類的實例。
    好處:當咱們對象所對應的類的類名發生變化的時候,咱們只須要改一下工廠類類裏面的實例化方法便可。不須要外部改全部的地方。
class Factory{

  static function createDatabase(){
       $db =new Database();
       return $db;
    }

}

$db=Factory::createDatabase();

註冊器模式理解:

  • 全局共享和交換對象
  • 單純使用工廠模式仍是要不斷的建立對象,結合註冊樹模式,就簡化了建立對象的麻煩。

代碼筆記1:php

Register.php,用來將一些對象註冊到全局的註冊樹上,能夠在任何地方訪問。set():將對象隱射到全局樹上,_unset():從樹上移除。get():去註冊到樹上的對象。在框架初始化的時候,會作註冊器的初始化操做,而後能夠在任何地方去訪問註冊器的方法。html

namespace IMooc;
class Register{
  protected static $objects;

  static function set($alias,$object){
    self::$objects[$alias] = $object;
  }

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

 function _unset($alias){
      unset(self::$objects[$alias]);

  }
}
在工廠模式寫下
class Factory{
static function createDatabase(){
    $db =Database::getInstance();
    Register::set('db1', $db);
    return $db;
  }
}
在index.php
$db = IMooc\Factory::createDatabase();
$db1 = \IMooc\Register::get('db1');

var_dump($db);
var_dump($db1);

代碼筆記2mysql

class Register
{
    protected static $objects =null;

    //註冊
    public static function bind($alias, $obj)
    {
        self::$objects[$alias]=$obj;
    }

    //解綁
    public static function unbind($alias)
    {
        unset(self::$objects[$alias]);
    }

    //得到
    public static function get($alias)
    {
        return self::$objects[$alias];
    }
}


class A
{

}

Register::bind('a',new A());
var_dump(Register::get('a'));

適配器模式理解:

  • 使用適配器策略是爲了更好的兼容。相似於手機電源適配器,若是能用一個充電器對全部手機充電固然是最方便的。不管什麼手機,都只須要拿一個充電器。不然,不一樣手機不一樣充電器,太麻煩。
  • 新建一個接口 IDatabase 而後在這個接口裏面申明統一的方法體,再讓不一樣的類去實現這個接口,和重寫其抽象方法。當咱們在入口文件使用到不一樣的類的時候,就只是實例化的類名不一樣,其它調用方法體的地方都一致

應用場景

如程序數據庫有關聯mysql、mysqli、pdo、sqlite、postgresql等操做,而你須要根據狀況換數據庫操做時,可使用適配器模式統一接口,這樣代碼中除了數據庫配置以外,就不須要作而外的更改。redis

同理cache(緩存)的場景也是,不管使用memcache仍是redis等,在更換的時候都會很方便,節約時間。sql

<?php
header('Content-Type:text/html;charset=utf-8');
/**
 * 適配器模式演示代碼
 * Target適配目標: IDataBase接口
 * Adaptee被適配者: mysql和mysql_i、postgresql的數據庫操做函數
 * Adapter適配器 :mysql類和mysql_i、postgresql類
 */

/**
 * Interface IDatabase 適配目標,規定的接口將被適配對象實現
 * 約定好統一的api行爲
 */
interface IDatabase
{
 // 定義數據庫鏈接方法
 public function connect($host, $username, $password, $database);
 // 定義數據庫查詢方法
 public function query($sql);
 // 關閉數據庫
 public function close();
}

/**
 * Class Mysql 適配器
 */
class Mysql implements IDatabase
{
 protected $connect; // 鏈接資源

/**
 * 實現鏈接方法
 *
 * @param $host host
 * @param $username 用戶名
 * @param $password 密碼
 * @param $database 數據庫名
 */
 public function connect($host, $username, $password, $database)
 {
 $connect = mysql_connect($host, $username, $password);
 mysql_select_db($database, $connect);
 $this->connect = $connect;
 //其餘操做
 }

/**
 * 實現查詢方法
 *
 * @param $sql 須要被查詢的sql語句
 * @return mi
 */
 public function query($sql)
 {
 return mysql_query($sql);
 }

// 實現關閉方法
 public function close()
 {
 mysql_close();
 }
}

/**
 * Class Mysql 適配器
 */
class Mysql_i implements IDatabase
{
 protected $connect; // 鏈接資源

/**
 * 實現鏈接方法
 *
 * @param $host host
 * @param $username 用戶名
 * @param $password 密碼
 * @param $database 數據庫名
 */
 public function connect($host, $username, $password, $database)
 {
 $connect = mysqli_connect($host, $username, $password, $database);
 $this->connect = $connect;
 //其餘操做
 }

/**
 * 實現查詢方法
 *
 * @param $sql 須要被查詢的sql語句
 */
 public function query($sql)
 {
 return mysqli_query($this->connect, $sql);
 }

// 實現關閉
 public function close()
 {
 mysqli_close($this->connect);
 }
}

/**
 * Class Postgresql 適配器
 */
class Postgresql implements IDatabase
{
 protected $connect; // 鏈接資源

/**
 * 實現鏈接方法
 *
 * @param $host
 * @param $username
 * @param $password
 * @param $database
 */
 public function connect($host, $username, $password, $database)
 {
 $this->connect = pg_connect("host=$host dbname=$database user=$username password=$password");
 //其餘操做
 }

/**
 * 實現查詢方法
 *
 * @param $sql 須要被查詢的sql語句
 */
 public function query($sql)
 {
 // 其餘操做
 }

// 實現關閉方法
 public function close()
 {
 }
}



/**
 * 客戶端使用演示
 * 這裏以mysql爲例
 * 只要模式設計好,不論有多少種數據庫,實現和調用方式都是同樣的
 * 由於都是實現的同一個接口,因此都是能夠隨意切換的
 */

$host = 'localhost';
$username = 'root';
$password = 'root';
$database = 'mysql';

//$client = new Postgresql();
//$client = new Mysql();
$client = new Mysql_i();
$client->connect($host, $username, $password, $database);
$result = $client->query("select * from db");
while ($rows = mysqli_fetch_array($result)) {
 var_dump($rows);
}
$client->close();

image

相關文章
相關標籤/搜索