PHP面向切面編程組件_PHP教程

來源:互聯網
上載者:User
我們使用MVC架構,例如CI、YII、cakePHP,原因之一就是:能夠使代碼便於維護。

但當商務邏輯不斷複雜時,在控制器中調用模型中的方法會越來越臃腫。

面向切面編程的思路,是解決不斷變化的商務邏輯與寫出便於維護代碼的解決方案之一。


下面是向切面式組件源碼,是根據AOP的思路設計的。

if (function_exists('__autoload')) {
trigger_error("Extension: It looks like your code is using an __autoload() function. Extension uses spl_autoload_register() which will bypass your __autoload() function and may break autoloading.", E_USER_WARNING);
}

spl_autoload_register(array('ExtensionFactory', 'autoload'));

class ExtensionFactory {

private static $extFamily = null;
private static $_classes = array(
'Extension' => '/Extension.php',
'ExtensionFamily' => '/ExtensionFamily.php'
);

/**
* Class autoloader. This method is provided to be invoked within an
* __autoload() magic method.
* @param string $className The name of the class to load.
*/
public static function autoload() {
foreach(self::$_classes as $v){
require_once dirname(__FILE__) . $v;
}
}

/**
* 必須先調用此方法來執行個體化擴充族,才能調用addExtension\removeExtension等
* @return ExtensionFamily
*/
public static function createExtension(){
self::$extFamily = new ExtensionFamily();
return self::$extFamily;
}

public static function removeExtension($extName){
if(is_null(self::$extFamily)){
throw new Exception("Please createExtension first");
return false;
}else{
unset(self::$extFamily->_extensionArray[$extName]);
}
}

public static function addExtension($extName, Extension $ext){
if(is_null(self::$extFamily)){
throw new Exception("Please createExtension first");
return false;
}else{
self::$extFamily->_extensionArray[$extName] = $ext;
}
}

public static function removeAllExtension(){
if(is_null(self::$extFamily)){
throw new Exception("Please createExtension first");
return false;
}else{
foreach(self::$extFamily->_extensionArray as $extName=>$ext){
unset(self::$extFamily->_extensionArray[$extName]);
}
}
}
}
if (function_exists('__autoload')) {
trigger_error("Extension: It looks like your code is using an __autoload() function. Extension uses spl_autoload_register() which will bypass your __autoload() function and may break autoloading.", E_USER_WARNING);
}

spl_autoload_register(array('ExtensionFactory', 'autoload'));

class ExtensionFactory {

private static $extFamily = null;
private static $_classes = array(
'Extension' => '/Extension.php',
'ExtensionFamily' => '/ExtensionFamily.php'
);

/**
* Class autoloader. This method is provided to be invoked within an
* __autoload() magic method.
* @param string $className The name of the class to load.
*/
public static function autoload() {
foreach(self::$_classes as $v){
require_once dirname(__FILE__) . $v;
}
}

/**
* 必須先調用此方法來執行個體化擴充族,才能調用addExtension\removeExtension等
* @return ExtensionFamily
*/
public static function createExtension(){
self::$extFamily = new ExtensionFamily();
return self::$extFamily;
}

public static function removeExtension($extName){
if(is_null(self::$extFamily)){
throw new Exception("Please createExtension first");
return false;
}else{
unset(self::$extFamily->_extensionArray[$extName]);
}
}

public static function addExtension($extName, Extension $ext){
if(is_null(self::$extFamily)){
throw new Exception("Please createExtension first");
return false;
}else{
self::$extFamily->_extensionArray[$extName] = $ext;
}
}

public static function removeAllExtension(){
if(is_null(self::$extFamily)){
throw new Exception("Please createExtension first");
return false;
}else{
foreach(self::$extFamily->_extensionArray as $extName=>$ext){
unset(self::$extFamily->_extensionArray[$extName]);
}
}
}
}


/**
* 擴充家族
*
* @author Mr.Jin
*/
class ExtensionFamily implements Extension{
public $_extensionArray = array();

/**
*
* @param type $extName 副檔名
* @param Extension $ext 實現Extension的對象
*/
public function addExtension($extName, Extension $ext){
$this->_extensionArray[$extName] = $ext;
}

public function beforeAppend(&$params){
foreach($this->_extensionArray as $ext){
$ext->beforeAppend($params);
}
}

public function afterAppend(&$params) {
foreach($this->_extensionArray as $ext){
$ext->afterAppend($params);
}
}
}

?>
/**
* 擴充家族
*
* @author Mr.Jin
*/
class ExtensionFamily implements Extension{
public $_extensionArray = array();

/**
*
* @param type $extName 副檔名
* @param Extension $ext 實現Extension的對象
*/
public function addExtension($extName, Extension $ext){
$this->_extensionArray[$extName] = $ext;
}

public function beforeAppend(&$params){
foreach($this->_extensionArray as $ext){
$ext->beforeAppend($params);
}
}

public function afterAppend(&$params) {
foreach($this->_extensionArray as $ext){
$ext->afterAppend($params);
}
}
}

?>

/**
* 擴充介面
*
* @author Mr.Jin
*/
interface Extension {
public function beforeAppend(&$params);

public function afterAppend(&$params);
}

?>
/**
* 擴充介面
*
* @author Mr.Jin
*/
interface Extension {
public function beforeAppend(&$params);

public function afterAppend(&$params);
}

?>

以上三個檔案實現了簡單的AOP組件。

下面是Demo:

/**
* 自訂Extension
* 使用者積分Extension
* 根據使用者是否登入,決定此次消費是否記錄使用者積分
*
* @author Mr.Jin
*/
class ExampleExtension implements Extension {
public $check=false;

public function beforeAppend(&$isLogin) {
if($isLogin){
$this->check = true;
}
}

public function afterAppend(&$pointer) {
if($this->check){
//add pointer
}else{
echo '未登入使用者,積分不錄入';
return;
}
}

}

?>
/**
* 自訂Extension
* 使用者積分Extension
* 根據使用者是否登入,決定此次消費是否記錄使用者積分
*
* @author Mr.Jin
*/
class ExampleExtension implements Extension {
public $check=false;

public function beforeAppend(&$isLogin) {
if($isLogin){
$this->check = true;
}
}

public function afterAppend(&$pointer) {
if($this->check){
//add pointer
}else{
echo '未登入使用者,積分不錄入';
return;
}
}

}

?>


demo.php
require_once('ExtensionFactory.php');//匯入組件本身

require_once('ExampleExtension.php');//匯入擴充

$ext = ExtensionFactory::createExtension();

ExtensionFactory::addExtension('example', new ExampleExtension());//積分錄入功能

/*
* 按照需求的變化,可以增加相應的Extension.
* eg.
* 新需求:新增會員類型,根據不同類型,進行價格優惠。
* 實現思路:
* 一、建立卡號類型工廠
* 二、建立SeniorMemberExtension、PuTongMeberExtension.
* 三、Factory 方法根據會員類型addExtension
*/

$isLogin = false; //假設使用者未登入

$ext->beforeAppend($isLogin);


/**
* 面向切面編程,最重要一點是:必須先分析出整個業務處理中,哪個才是重點。
* 這裡的重點是訂單的入庫。
* 在訂單入庫之前可能商務邏輯不斷增加,例如:登入驗證、卡上餘額驗證等
* 在訂單入庫之後:積分處理、訂單監控等
*/
echo "此處是主要商務邏輯:訂單入庫\r\n";

$pointer = 100;

$ext->afterAppend($pointer);
require_once('ExtensionFactory.php');//匯入組件本身

require_once('ExampleExtension.php');//匯入擴充

$ext = ExtensionFactory::createExtension();

ExtensionFactory::addExtension('example', new ExampleExtension());//積分錄入功能

/*
* 按照需求的變化,可以增加相應的Extension.
* eg.
* 新需求:新增會員類型,根據不同類型,進行價格優惠。
* 實現思路:
* 一、建立卡號類型工廠
* 二、建立SeniorMemberExtension、PuTongMeberExtension.
* 三、Factory 方法根據會員類型addExtension
*/

$isLogin = false; //假設使用者未登入

$ext->beforeAppend($isLogin);


/**
* 面向切面編程,最重要一點是:必須先分析出整個業務處理中,哪個才是重點。
* 這裡的重點是訂單的入庫。
* 在訂單入庫之前可能商務邏輯不斷增加,例如:登入驗證、卡上餘額驗證等
* 在訂單入庫之後:積分處理、訂單監控等
*/
echo "此處是主要商務邏輯:訂單入庫\r\n";

$pointer = 100;

$ext->afterAppend($pointer);
運行結果:
此處是主要商務邏輯:訂單入庫
未登入使用者,積分不錄入

摘自 God's blog

http://www.bkjia.com/PHPjc/478518.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/478518.htmlTechArticle我們使用MVC架構,例如CI、YII、cakePHP,原因之一就是:能夠使代碼便於維護。 但當商務邏輯不斷複雜時,在控制器中調用模型中的方法會越...

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.