4種常見的 PHP 設計模式

工廠模式

在大型系統中,許多代碼依賴於少數幾個關鍵類。須要更改這些類時,可能會出現困難。例如,假設您有一個從文件讀取的 User 類。您但願將其更改成從數據庫讀取的其餘類,可是,全部的代碼都引用從文件讀取的原始類。這時候,使用工廠模式會很方便。php

工廠模式 是一種類,它具備爲您建立對象的某些方法。您可使用工廠類建立對象,而不直接使用 new。這樣,若是您想要更改所建立的對象類型,只需更改該工廠便可。使用該工廠的全部代碼會自動更改。mysql

清單 1 顯示工廠類的一個示列。等式的服務器端包括兩個部分:數據庫和一組 PHP 頁面,這些頁面容許您添加反饋、請求反饋列表並獲取與特定反饋相關的文章。算法

清單 1. Factory1.phpsql

1數據庫

2設計模式

3服務器

4併發

5測試

6ui

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

<?php

interface IUser

{

  function getName();

}

 

class User implements IUser

{

  public function __construct( $id ) { }

 

  public function getName()

  {

    return "Jack";

  }

}

 

class UserFactory

{

  public static function Create( $id )

  {

    return new User( $id );

  }

}

 

$uo = UserFactory::Create( 1 );

echo$uo->getName()."\n" );

?>

  

單元素模式(單列模式)

某些應用程序資源是獨佔的,由於有且只有一個此類型的資源。例如,經過數據庫句柄到數據庫的鏈接是獨佔的。您但願在應用程序中共享數據庫句柄,由於在保持鏈接打開或關閉時,它是一種開銷,在獲取單個頁面的過程當中更是如此。

單元素模式能夠知足此要求。若是應用程序每次包含且僅包含一個對象,那麼這個對象就是一個單元素(Singleton)。清單 3 中的代碼顯示了 PHP V5 中的一個數據庫鏈接單元素。

  1. php的應用主要在於數據庫應用, 一個應用中會存在大量的數據庫操做, 在使用面向對象的方式開發時, 若是使用單例模式, 則能夠避免大量的new 操做消耗的資源,還能夠減小數據庫鏈接這樣就不容易出現 too many connections狀況。
  2. 若是系統中須要有一個類來全局控制某些配置信息, 那麼使用單例模式能夠很方便的實現. 這個能夠參看zend Framework的FrontController部分。
  3. 在一次頁面請求中, 便於進行調

清單 3. Singleton.php

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

<?php

require_once("DB.php");

 

class DatabaseConnection

{

  public static function get()

  {

    static $db = null;

    if $db == null )

      $db new DatabaseConnection();

    return $db;

  }

 

  private $_handle = null;

 

  private function __construct()

  {

    $dsn 'mysql://root:password@localhost/photos';

    $this->_handle =& DB::Connect( $dsnarray() );

  }

   

  public function handle()

  {

    return $this->_handle;

  }

}

 

print"Handle = ".DatabaseConnection::get()->handle()."\n" );

print"Handle = ".DatabaseConnection::get()->handle()."\n" );

?>

  您可使用全局變量存儲數據庫句柄,可是,該方法僅適用於較小的應用程序。在較大的應用程序中,應避免使用全局變量,並使用對象和方法訪問資源。

觀察者模式

觀察者模式爲您提供了避免組件之間緊密耦合的另外一種方法。該模式很是簡單:一個對象經過添加一個方法(該方法容許另外一個對象,即觀察者 註冊本身)使自己變得可觀察。當可觀察的對象更改時,它會將消息發送到已註冊的觀察者。這些觀察者使用該信息執行的操做與可觀察的對象無關。結果是對象能夠相互對話,而沒必要了解緣由。

一個簡單示例是系統中的用戶列表。清單 4 中的代碼顯示一個用戶列表,添加用戶時,它將發送出一條消息。添加用戶時,經過發送消息的日誌觀察者能夠觀察此列表。

清單 4. Observer.php

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

<?php

interface IObserver

{

  function onChanged( $sender$args );

}

 

interface IObservable

{

  function addObserver( $observer );

}

 

class UserList implements IObservable

{

  private $_observers array();

 

  public function addCustomer( $name )

  {

    foreach$this->_observers as $obs )

      $obs->onChanged( $this$name );

  }

 

  public function addObserver( $observer )

  {

    $this->_observers []= $observer;

  }

}

 

class UserListLogger implements IObserver

{

  public function onChanged( $sender$args )

  {

    echo"'$args' added to user list\n" );

  }

}

 

$ul new UserList();

$ul->addObserver( new UserListLogger() );

$ul->add

  

此代碼定義四個元素:兩個接口和兩個類。IObservable 接口定義能夠被觀察的對象,UserList 實現該接口,以便將自己註冊爲可觀察。IObserver 列表定義要經過怎樣的方法才能成爲觀察者,UserListLogger 實現 IObserver 接口。圖 4 的 UML 中展現了這些元素。

圖 4. 可觀察的用戶列表和用戶列表事件日誌程序

 

若是在命令行中運行它,您將看到如下輸出:

% php observer.php 
'Jack' added to user list
%

測試代碼建立 UserList,並將 UserListLogger 觀察者添加到其中。而後添加一個消費者,並將這一更改通知 UserListLogger

認識到 UserList 不知道日誌程序將執行什麼操做很關鍵。可能存在一個或多個執行其餘操做的偵聽程序。例如,您可能有一個向新用戶發送消息的觀察者,歡迎新用戶使用該系統。這種方法的價值在於 UserList 忽略全部依賴它的對象,它主要關注在列表更改時維護用戶列表併發送消息這一工做。

此模式不限於內存中的對象。它是在較大的應用程序中使用的數據庫驅動的消息查詢系統的基礎。

 

策略模式

咱們講述的最後一個設計模式是策略 模式。在此模式中,算法是從複雜類提取的,於是能夠方便地替換。例如,若是要更改搜索引擎中排列頁的方法,則策略模式是一個不錯的選擇。思考一下搜索引擎的幾個部分 —— 一部分遍歷頁面,一部分對每頁排列,另外一部分基於排列的結果排序。在複雜的示例中,這些部分都在同一個類中。經過使用策略模式,您可將排列部分放入另外一個類中,以便更改頁排列的方式,而不影響搜索引擎的其他代碼。

清單 5. Strategy.php

相關文章
相關標籤/搜索