我们使用mvc框架,例如ci、yii、cakephp,原因之一就是:能够使代码便于维护。

但当业务逻辑不断复杂时,在控制器中调用模型中的方法会越来越臃肿。

面向切面的思路,是解决不断变化的业务逻辑与写出便于维护代码的解决方法之一。

 

下面是向切面式,是根据aop的思路设计的。

 

 

<?php 
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]); 
            } 
        } 
    } 

<?php
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]);
            }
        }
    }
}

 

<?php 
/**
 * 扩展家族
 *
 * @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); 
        } 
    } 

 
?> 
<?php
/**
 * 扩展家族
 *
 * @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);
        }
    }
}

?>

<?php 
/**
 * 扩展接口
 *
 * @author mr.jin
 */ 
interface extension { 
    public function beforeappend(&$params); 
     
    public function afterappend(&$params); 

 
?> 
<?php
/**
 * 扩展接口
 *
 * @author mr.jin
 */
interface extension {
    public function beforeappend(&$params);
   
    public function afterappend(&$params);
}

?>

以上三个文件实现了简单的aop组件。

 

下面是demo:

<?php 
/**
 * 自定义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; 
        } 
    } 
 

 
?> 
<?php
/**
 * 自定义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
<?php 
require_once(‘extensionfactory.php’);//导入组件本身  
 
require_once(‘exampleextension.php’);//导入扩展  
 
$ext = extensionfactory::createextension(); 
 
extensionfactory::addextension(‘example’, new exampleextension());//积分录入功能  
 
/*
 * 按照需求的变化,可以增加相应的extension.
 * eg.
 * 新需求:新增会员类型,根据不同类型,进行价格优惠。
 * 实现思路:
 * 一、建立卡号类型工厂
 * 二、建立seniormemberextension、putongmeberextension.
 * 三、工厂方法根据会员类型addextension
 */ 
 
$islogin = false; //假设用户未登录  
 
$ext->beforeappend($islogin); 
 
 
/**
 * 面向切面编程,最重要一点是:必须先分析出整个业务处理中,哪个才是重点。
 * 这里的重点是订单的入库。
 * 在订单入库之前可能业务逻辑不断增加,例如:登录验证、卡上余额验证等
 * 在订单入库之后:积分处理、订单监控等
 */ 
echo “此处是主要业务逻辑:订单入库\r\n”; 
 
$pointer = 100; 
 
$ext->afterappend($pointer); 
<?php
require_once(‘extensionfactory.php’);//导入组件本身

require_once(‘exampleextension.php’);//导入扩展

$ext = extensionfactory::createextension();

extensionfactory::addextension(‘example’, new exampleextension());//积分录入功能

/*
 * 按照需求的变化,可以增加相应的extension.
 * eg.
 * 新需求:新增会员类型,根据不同类型,进行价格优惠。
 * 实现思路:
 * 一、建立卡号类型工厂
 * 二、建立seniormemberextension、putongmeberextension.
 * 三、工厂方法根据会员类型addextension
 */

$islogin = false; //假设用户未登录

$ext->beforeappend($islogin);

/**
 * 面向切面编程,最重要一点是:必须先分析出整个业务处理中,哪个才是重点。
 * 这里的重点是订单的入库。
 * 在订单入库之前可能业务逻辑不断增加,例如:登录验证、卡上余额验证等
 * 在订单入库之后:积分处理、订单监控等
 */
echo “此处是主要业务逻辑:订单入库\r\n”;

$pointer = 100;

$ext->afterappend($pointer);
运行结果:
此处是主要业务逻辑:订单入库
未登录用户,积分不录入

 摘自 god’s blog