欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

PHP常用的三種設(shè)計(jì)模式匯總

 更新時(shí)間:2016年08月28日 09:00:19   投稿:hebedich  
本文給大家簡(jiǎn)單介紹了PHP中最常用的三種設(shè)計(jì)模式:?jiǎn)卫O(shè)計(jì)模式、工廠設(shè)計(jì)模式和觀察者設(shè)計(jì)模式。都是個(gè)人的一些經(jīng)驗(yàn)總結(jié),希望小伙伴們能夠喜歡

本篇文章是學(xué)習(xí)PHP中常用的三種設(shè)計(jì)模式的筆記及總結(jié),不管采用哪一門語言開發(fā)什么,幾乎都會(huì)使用到設(shè)計(jì)模式,我們?yōu)槭裁葱枰O(shè)計(jì)模式呢?它的誕生對(duì)于我們開發(fā)人員來說有什么樣的作用與意義呢?

相信做iOS開發(fā)的人員對(duì)設(shè)計(jì)模式也會(huì)挺熟悉吧?比如單例設(shè)計(jì)模式、工廠設(shè)計(jì)模式、觀察者模式、MVC框架結(jié)構(gòu)設(shè)計(jì)模式等。

接下來我們一起來學(xué)習(xí)PHP中最常用的三種設(shè)計(jì)模式:?jiǎn)卫O(shè)計(jì)模式、工廠設(shè)計(jì)模式和觀察者設(shè)計(jì)模式。

單例設(shè)計(jì)模式

所謂單例模式,即在應(yīng)用程序中最多只有該類的一個(gè)實(shí)例存在,一旦創(chuàng)建,就會(huì)一直存在于內(nèi)存中!

單例設(shè)計(jì)模式常應(yīng)用于數(shù)據(jù)庫類設(shè)計(jì),采用單例模式,只連接一次數(shù)據(jù)庫,防止打開多個(gè)數(shù)據(jù)庫連接。

一個(gè)單例類應(yīng)具備以下特點(diǎn):

單例類不能直接實(shí)例化創(chuàng)建,而是只能由類本身實(shí)例化。因此,要獲得這樣的限制效果,構(gòu)造函數(shù)必須標(biāo)記為private,從而防止類被實(shí)例化。

需要一個(gè)私有靜態(tài)成員變量來保存類實(shí)例和公開一個(gè)能訪問到實(shí)例的公開靜態(tài)方法。

在PHP中,為了防止他人對(duì)單例類實(shí)例克隆,通常還為其提供一個(gè)空的私有__clone()方法。

單例模式的例子:

 
<?php
 
/**
* Singleton of Database
*/
class Database
{
  // We need a static private variable to store a Database instance.
  privatestatic $instance;
 
  // Mark as private to prevent it from being instanced.
  privatefunction__construct()
  {
    // Do nothing.
  }
 
  privatefunction__clone() 
  {
    // Do nothing.
  }
 
  publicstatic functiongetInstance() 
  {
    if (!(self::$instanceinstanceofself)) {
      self::$instance = newself();
    }
 
    returnself::$instance;
  }
}
 
$a =Database::getInstance();
$b =Database::getInstance();
 
// true
var_dump($a === $b);
 

工廠設(shè)計(jì)模式

工廠設(shè)計(jì)模式常用于根據(jù)輸入?yún)?shù)的不同或者應(yīng)用程序配置的不同來創(chuàng)建一種專門用來實(shí)例化并返回其對(duì)應(yīng)的類的實(shí)例。

我們舉例子,假設(shè)矩形、圓都有同樣的一個(gè)方法,那么我們用基類提供的API來創(chuàng)建實(shí)例時(shí),通過傳參數(shù)來自動(dòng)創(chuàng)建對(duì)應(yīng)的類的實(shí)例,他們都有獲取周長和面積的功能。

 
<?php
 
interfaceInterfaceShape 
{
 functiongetArea();
 functiongetCircumference();
}
 
/**
* 矩形
*/
class Rectangle implementsInterfaceShape
{
  private $width;
  private $height;
  
  publicfunction__construct($width, $height)
  {
    $this->width = $width;
    $this->height = $height;
  }
 
  publicfunctiongetArea() 
  {
    return $this->width* $this->height;
  }
 
  publicfunctiongetCircumference()
  {
    return 2 * $this->width + 2 * $this->height;
  }
}
 
/**
* 圓形
*/
class Circle implementsInterfaceShape
{
  private $radius;
 
  function__construct($radius)
  {
    $this->radius = $radius;
  }
 
 
  publicfunctiongetArea() 
  {
    return M_PI * pow($this->radius, 2);
  }
 
  publicfunctiongetCircumference()
  {
    return 2 * M_PI * $this->radius;
  }
}
 
/**
* 形狀工廠類
*/
class FactoryShape 
{ 
  publicstatic functioncreate()
  {
    switch (func_num_args()) {
      case1:
      return newCircle(func_get_arg(0));
      case2:
      return newRectangle(func_get_arg(0), func_get_arg(1));
      default:
        # code...
        break;
    }
  } 
}
 
$rect =FactoryShape::create(5, 5);
// object(Rectangle)#1 (2) { ["width":"Rectangle":private]=> int(5) ["height":"Rectangle":private]=> int(5) }
var_dump($rect);
echo "<br>";
 
// object(Circle)#2 (1) { ["radius":"Circle":private]=> int(4) }
$circle =FactoryShape::create(4);
var_dump($circle);
 

觀察者設(shè)計(jì)模式

觀察者模式是挺常見的一種設(shè)計(jì)模式,使用得當(dāng)會(huì)給程序帶來非常大的便利,使用得不當(dāng),會(huì)給后來人一種難以維護(hù)的想法。

什么是觀察者模式?一個(gè)對(duì)象通過提供方法允許另一個(gè)對(duì)象即觀察者 注冊(cè)自己)使本身變得可觀察。當(dāng)可觀察的對(duì)象更改時(shí),它會(huì)將消息發(fā)送到已注冊(cè)的觀察者。這些觀察者使用該信息執(zhí)行的操作與可觀察的對(duì)象無關(guān)。結(jié)果是對(duì)象可以相互對(duì)話,而不必了解原因。觀察者模式是一種事件系統(tǒng),意味著這一模式允許某個(gè)類觀察另一個(gè)類的狀態(tài),當(dāng)被觀察的類狀態(tài)發(fā)生改變的時(shí)候,觀察類可以收到通知并且做出相應(yīng)的動(dòng)作;觀察者模式為您提供了避免組件之間緊密耦??聪旅胬幽憔兔靼琢耍?/p>

 
<?php
 
/*
觀察者接口
*/
interfaceInterfaceObserver
{
  functiononListen($sender, $args);
  functiongetObserverName();
}
 
// 可被觀察者接口
interfaceInterfaceObservable
{
  functionaddObserver($observer);
  functionremoveObserver($observer_name);
}
 
// 觀察者抽象類
abstractclass Observer implementsInterfaceObserver
{
  protected $observer_name;
 
  functiongetObserverName() 
  {
    return $this->observer_name;
  }
 
  functiononListen($sender, $args)
  {
 
  }
}
 
// 可被觀察類
abstractclass Observable implementsInterfaceObservable 
{
  protected $observers = array();
 
  publicfunctionaddObserver($observer) 
  {
    if ($observerinstanceofInterfaceObserver) 
    {
      $this->observers[] = $observer;
    }
  }
 
  publicfunctionremoveObserver($observer_name) 
  {
    foreach ($this->observersas $index => $observer) 
    {
      if ($observer->getObserverName() === $observer_name) 
      {
        array_splice($this->observers, $index, 1);
        return;
      }
    }
  }
}
 
// 模擬一個(gè)可以被觀察的類
class A extendsObservable 
{
  publicfunctionaddListener($listener) 
  {
    foreach ($this->observersas $observer) 
    {
      $observer->onListen($this, $listener);
    }
  }
}
 
// 模擬一個(gè)觀察者類
class B extendsObserver 
{
  protected $observer_name = 'B';
 
  publicfunctiononListen($sender, $args) 
  {
    var_dump($sender);
    echo "<br>";
    var_dump($args);
    echo "<br>";
  }
}
 
// 模擬另外一個(gè)觀察者類
class C extendsObserver 
{
  protected $observer_name = 'C';
 
  publicfunctiononListen($sender, $args) 
  {
    var_dump($sender);
    echo "<br>";
    var_dump($args);
    echo "<br>";
  }
}
 
$a = new A();
// 注入觀察者
$a->addObserver(new B());
$a->addObserver(new C());
 
// 可以看到觀察到的信息
$a->addListener('D');
 
// 移除觀察者
$a->removeObserver('B');
 
// 打印的信息:
// object(A)#1 (1) { ["observers":protected]=> array(2) { [0]=> object(B)#2 (1) { ["observer_name":protected]=> string(1) "B" } [1]=> object(C)#3 (1) { ["observer_name":protected]=> string(1) "C" } } }
// string(1) "D"
// object(A)#1 (1) { ["observers":protected]=> array(2) { [0]=> object(B)#2 (1) { ["observer_name":protected]=> string(1) "B" } [1]=> object(C)#3 (1) { ["observer_name":protected]=> string(1) "C" } } }
// string(1) "D"
 

小結(jié)

初入PHP的世界,目前只了解這些基本的設(shè)計(jì)模式,慢慢學(xué)著去應(yīng)用!如果文中有不對(duì)之處,請(qǐng)?jiān)谠u(píng)論中指出,我會(huì)在明確之后更正文章內(nèi)容!

相關(guān)文章

最新評(píng)論