Upload
jace-ju
View
3.173
Download
1
Embed Size (px)
Citation preview
Patterns in Zend Framework
Jace Ju
Patterns
Simple Factory
Singleton
Adapter
Strategy
Composite
Chain of Responsibility
Simple Factory
概念
不讓程序依賴類別名稱。
利用設定來動態建立物件。
範例: Zend_Db::factory()
factory() 提供參數以建立不同的 Db Adapter 。
應用程式可以透過設定來配置 factory 參數。
$db = Zend_Db::factory('pdo_mysql', array(
'host' => '127.0.0.1',
'username' => 'www',
'password' => '123456',
'dbname' => 'test',
));
echo get_class($db), "\n"; // Zend_Db_Adapter_Pdo_Mysql
$db = Zend_Db::factory('mysqli', array(
'host' => '127.0.0.1',
'username' => 'www',
'password' => '123456',
'dbname' => 'test',
));
echo get_class($db), "\n"; // Zend_Db_Adapter_Mysqli
Zend_Db::factory()
概念
整個系統只需要單一個物件實體。
通常用以取代全域變數。
Singleton
範例: Zend_Controller_Front
整個應用程式只需要一個 Front Controller 。
Application Resource 及 Controller Plugin 可以透過 getInstance 方法來取得 Front Controller 的唯一實體。
$frontController = Zend_Controller_Front::getInstance();
Adapter
概念
將已實作功能但介面不同的類別庫或函式庫整合進來。
通常用於整合第三方套件。
範例: Zend_Db_Adapter
轉接微軟寫好的 Sqlsrv 函式庫。
class Zend_Db_Adapter_Sqlsrv extends Zend_Db_Adapter_Abstract
{
protected function _connect()
{
// ...
$this->_connection = sqlsrv_connect(...);
}
public function closeConnection()
{
// ...
sqlsrv_close($this->_connection);
// ...
}
}
$dbAdapter = new Zend_Db_Adapter_Sqlsrv(...);
print_r($dbAdapter->listTables());
$dbAdapter->closeConnection();
Zend_Db_Adapter
Strategy
概念
採用不同的策略來處理相同的問題。
依照情境的不同來選擇策略。
範例: Zend_Cache
Zend_Cache 提供不同的 Backend 儲存方式。
$cache = new Zend_Cache_Core();
$cache->setBackend(new Zend_Cache_Backend_File(array(
'cache_dir' => dirname(__FILE__),
)));
$data = $cache->load('test');
if (!$data) {
$data = 'Cached data';
$cache->save($data, 'test');
}
print_r($data);
Zend_Cache
Composite
概念
對群體與個體一視同仁。
通常用於樹狀結構。
範例: Zend_Filter
Zend_Filter 可以加入其他 Filter 。
Zend_Filter 為 Composite ,其他實作Zend_Filter_Interface 的子類別為 Leaf 。
$unfiltered = 'ab#12.3$%cde';
$filter = new Zend_Filter();
$value = $filter->filter($unfiltered);
echo $value, "\n"; // ab#12.3$%cde
$filter->addFilter(new Zend_Filter_Alnum());
$value = $filter->filter($unfiltered);
echo $value, "\n"; // ab123cde
$filter->addFilter(new Zend_Filter_Digits());
$value = $filter->filter($unfiltered);
echo $value, "\n"; // 123
Zend_Filter
範例: Zend_Config
Composite 的變形,Zend_Config 本身就是 Leaf 及 Composite。
$config = new Zend_Config_Ini(dirname(__FILE__) . '/config.ini');
print_r($config->toArray()); // Composite
foreach ($config as $name => $section) {
echo $name, " ", get_class($section), "\n";
print_r($section->toArray()); // Composite
}
$dbConfig = $config->production->db;
echo get_class($dbConfig), "\n";
print_r($dbConfig->toArray()); // Leaf
Chain of Responsibility
概念
定義一連串的處理機制來處理某個需求。
在找到符合的規則後就離開。
可以用來取代 if ... elseif 。
範例: Zend_Controller_Router
只處理符合的 Url 。
$router = new Zend_Controller_Router_Rewrite();
$requests = array(
new Zend_Controller_Request_Http('http://localhost/login'),
new Zend_Controller_Request_Http('http://localhost/article/123'),
);
$loginRoute = new Zend_Controller_Router_Route_Static('login', array(
'controller' => 'user',
'action' => 'login',
));
$articleRoute = new Zend_Controller_Router_Route_Regex('article/(\d+)', array(
'controller' => 'blog',
'action' => 'article',
), array(
1 => 'id',
));
$router->addRoute('login', $loginRoute);
$router->addRoute('article', $articleRoute);
foreach ($requests as $request) {
$router->route($request);
print_r($request->getParams());
}
Zend_Controller_Router
其他
Patterns 和物件導向設計原則讓 Zend Framewrork 具有強大的擴充性。
Zend Framework 還實作了許多企業級的Patterns ,例如: Table Data Gateway 、 Front Controller 、 Registry ...
總結
在設計類別時,不一定要先考慮 Patterns 。
不必拘泥於 Patterns 的形。
一個類別體系不一定只有一種 Pattern 。
Patterns 之間可以互相合作。
謝謝