1.原廠模式
原廠模式是一種類,它具有為您建立對象的某些方法。您可以使用工廠類建立對象,而不直接使用 new。這樣,如果您想要更改所建立的物件類型,只需更改該工廠即可。使用該工廠的所有代碼會自動更改。
<?php<br />interface IUser //定義一個介面<br />{<br /> function getName();<br />}</p><p>class User implements IUser //定義一個類繼承該介面,並且實現該介面的所有方法<br />{<br /> public function __construct( $id ) { }</p><p> public function getName()<br /> {<br /> return "Jack";<br /> }<br />}</p><p>class UserFactory //定義一個類包含公用靜態方法可以直接調用,而不需要NEW的執行個體化<br />{<br /> public static function Create( $id )<br /> {<br /> return new User( $id );<br /> }<br />}</p><p>$uo = UserFactory::Create( 1 );<br />echo( $uo->getName()."/n" );<br />?><br />
另一種更簡潔的原廠模式:
<?php<br />interface IUser //定義一個介面<br />{<br /> function getName();<br />}</p><p>class User implements IUser //繼承介面的類<br />{<br /> public static function Load( $id ) //靜態載入本類的方法並返回對象<br /> {<br /> return new User( $id );<br /> }</p><p> public static function Create( ) // 同上,但不需要參數<br /> {<br /> return new User( null );<br /> }</p><p> public function __construct( $id ) { }</p><p> public function getName() //實現介面中的方法<br /> {<br /> return "Jack";<br /> }<br />}</p><p>$uo = User::Load( 1 );<br />echo( $uo->getName()."/n" );<br />?></p><p>
單元素模式:
某些應用程式資源是獨佔的,因為有且只有一個此類型的資源。例如,通過資料庫控制代碼到資料庫的串連是獨佔的。您希望在應用程式中共用資料庫控制代碼,因為在保持串連開啟或關閉時,它是一種開銷,在擷取單個頁面的過程中更是如此。
單元素模式可以滿足此要求。如果應用程式每次包含且僅包含一個對象,那麼這個對象就是一個單元素(Singleton)。清單 3 中的代碼顯示了 PHP V5 中的一個資料庫連接單元素。
您可以使用全域變數儲存資料庫控制代碼,但是,該方法僅適用於較小的應用程式。在較大的應用程式中,應避免使用全域變數,並使用對象和方法訪問資源。
<?php<br />require_once("DB.php"); //載入資料庫設定檔</p><p>class DatabaseConnection //資料庫連接類<br />{<br /> public static function get() //靜態共有方法()<br /> {<br /> static $db = null; //靜態變數設為空白<br /> if ( $db == null ) //如果靜態變數為空白才執行下面的操作<br /> $db = new DatabaseConnection();<br /> return $db;<br /> }</p><p> private $_handle = null; //設定一個私人的變數</p><p> private function __construct() //設定一個私人的初始化方法<br /> {<br /> $dsn = 'mysql://root:password@localhost/photos';<br /> $this->_handle =& DB::Connect( $dsn, array() );<br /> }</p><p> public function handle()<br /> {<br /> return $this->_handle;<br /> }<br />}</p><p>print( "Handle = ".DatabaseConnection::get()->handle()."/n" );<br />print( "Handle = ".DatabaseConnection::get()->handle()."/n" );<br />?>
觀察者模式為您提供了避免組件之間緊密耦合的另一種方法。該模式非常簡單:一個對象通過添加一個方法(該方法允許另一個對象,即觀察者 註冊自己)使本身變得可觀察。當可觀察的對象更改時,它會將訊息發送到登入的觀察者。這些觀察者使用該資訊執行的操作與可觀察的對象無關。結果是對象可以相互對話,而不必瞭解原因。
一個簡單樣本是系統中的使用者列表。清單 4 中的代碼顯示一個使用者列表,添加使用者時,它將發送出一條訊息。添加使用者時,通過發送訊息的日誌觀察者可以觀察此列表。
<?php<br />interface IObserver //定義個一個介面<br />{<br /> function onChanged( $sender, $args );<br />}</p><p>interface IObservable //定義個一個介面<br />{<br /> function addObserver( $observer );<br />}</p><p>class UserList implements IObservable //繼承第二個介面<br />{<br /> private $_observers = array();</p><p> public function addCustomer( $name )<br /> {<br /> foreach( $this->_observers as $obs )<br /> $obs->onChanged( $this, $name );//調用觀察者介面來使用多個介面<br /> }</p><p> public function addObserver( $observer ) //添加觀察者模式介面<br /> {<br /> $this->_observers []= $observer;<br /> }<br />}</p><p>class UserListLogger implements IObserver //繼承第一個介面<br />{<br /> public function onChanged( $sender, $args )<br /> {<br /> echo( "'$args' added to user list/n" );<br /> }<br />}</p><p>class UserListLogger2 implements IObserver //繼承第一個介面2<br />{<br /> public function onChanged( $sender, $args )<br /> {<br /> echo( "'$args' 2222222222222222 list/n" );<br /> }<br />}</p><p>$ul = new UserList();<br />$ul->addObserver( new UserListLogger() );<br />$ul->addObserver( new UserListLogger2() );<br />$ul->addCustomer( "Jack" );<br />?>
命令鏈模式
命令鏈模式以鬆散耦合主題為基礎,發送訊息、命令和請求,或通過一組處理常式發送任意內容。每個處理常式都會自行判斷自己能否處理請求。如果可以,該請求被處理,進程停止。您可以為系統添加或移除處理常式,而不影響其他處理常式。
總體來說命令鏈模式就是讓系統定義多個執行介面,而通過一個命令連結口來執行!
<?php<br />interface ICommand //定義一個介面<br />{<br /> function onCommand( $name, $args );<br />}</p><p>class CommandChain //一個命令連結口類<br />{<br /> private $_commands = array();</p><p> public function addCommand( $cmd )//增加命令連結口<br /> {<br /> $this->_commands []= $cmd;<br /> }</p><p> public function runCommand( $name, $args )//執行命令鏈函數介面<br /> {<br /> foreach( $this->_commands as $cmd )<br /> {<br /> if ( $cmd->onCommand( $name, $args ) )<br /> return;<br /> }<br /> }<br />}</p><p>class UserCommand implements ICommand //定義一個介面類<br />{<br /> public function onCommand( $name, $args )<br /> {<br /> if ( $name != 'addUser' ) return false;<br /> echo( "UserCommand handling 'addUser'/n" );<br /> return true;<br /> }<br />}</p><p>class MailCommand implements ICommand //定義一個介面類<br />{<br /> public function onCommand( $name, $args )<br /> {<br /> if ( $name != 'mail' ) return false;<br /> echo( "MailCommand handling 'mail'/n" );<br /> return true;<br /> }<br />}</p><p>$cc = new CommandChain();<br />$cc->addCommand( new UserCommand() );<br />$cc->addCommand( new MailCommand() );<br />$cc->runCommand( 'addUser', null );<br />$cc->runCommand( 'mail', null );<br />?><br />
策略模式
我們講述的最後一個設計模式是策略模式。在此模式中,演算法是從複雜類提取的,因而可以方便地替換。例如,如果要更改搜尋引擎中排列頁的方法,則策略模式是一個不錯的選擇。思考一下搜尋引擎的幾個部分部分遍曆頁面,一部分對每頁排列,另一部分基於排列的結果排序。在複雜的樣本中,這些部分都在同一個類中。通過使用原則模式,您可將排列部分放入另一個類中,以便更改頁排列的方式,而不影響搜尋引擎的其餘代碼。
<?php<br />interface IStrategy //定義一個介面<br />{<br /> function filter( $record );<br />}</p><p>class FindAfterStrategy implements IStrategy //繼承介面<br />{<br /> private $_name;</p><p> public function __construct( $name )<br /> {<br /> $this->_name = $name;<br /> }</p><p> public function filter( $record )<br /> {<br /> return strcmp( $this->_name, $record ) <= 0;//返回兩個字串的大小<br /> }<br />}</p><p>class RandomStrategy implements IStrategy //繼承介面隨機比較<br />{<br /> public function filter( $record )<br /> {<br /> return rand( 0, 1 ) >= 0.5;<br /> }<br />}</p><p>class UserList<br />{<br /> private $_list = array();</p><p> public function __construct( $names ) //使用者註冊<br /> {<br /> if ( $names != null )<br /> {<br /> foreach( $names as $name )<br /> {<br /> $this->_list []= $name;<br /> }<br /> }<br /> }</p><p> public function add( $name )<br /> {<br /> $this->_list []= $name;<br /> }</p><p> public function find( $filter ) //策略模式介面 (傳遞進來一個方法對象)<br /> {<br /> $recs = array();<br /> foreach( $this->_list as $user )<br /> {<br /> if ( $filter->filter( $user ) )//將傳遞進來的名字和_name比較<br /> $recs []= $user;<br /> }<br /> return $recs;<br /> }<br />}</p><p>$ul = new UserList( array( "Andy", "Jack", "Lori", "Megan" ) );<br />$f1 = $ul->find( new FindAfterStrategy( "J" ) );//初始化_name 並賦值<br />print_r( $f1 );</p><p>$f2 = $ul->find( new RandomStrategy() );<br />print_r( $f2 );<br />?><br />