PHP框架的三層架構設計真的合適么?

    對于基本的Web開發(fā),我們已經(jīng)習慣了MVC架構。模型層(M)提供持久化數(shù)據(jù)對象與數(shù)據(jù)訪問,控制層(C)完成業(yè)務邏輯處理,視圖層(V)提供模板表現(xiàn)。其中控制層與模型層和視圖層交互形成整個系統(tǒng)。

目前創(chuàng)新互聯(lián)建站已為超過千家的企業(yè)提供了網(wǎng)站建設、域名、雅安服務器托管、綿陽服務器托管、企業(yè)網(wǎng)站設計、新華網(wǎng)站維護等服務,公司將堅持客戶導向、應用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。

    這種分層方式在邏輯上實現(xiàn)了解耦與分離,很多語言如Java和Python的框架都有各自的實現(xiàn)方式,如Struts采用Bean+JSP+Hibernate的方式實現(xiàn)。Django采用中間件的方式實現(xiàn)。無論是JAVA框架的實現(xiàn)方式還是Python框架的實現(xiàn)方式,都比較好的解決了MVC之間的交互問題,使得每個層次成為單獨的構件,每一層的構件可復用在其它地方。如Java Bean除了可供JSP使用,還可包裝成Soap服務。這樣既保證了層之間的邏輯分離,也保證了層之間的物理分離。如Java Bean可以單獨被部署到分布式應用服務器上。EJB就是一個很好的例子。而對于目前廣泛應用的一些PHP框架,在實現(xiàn)上感覺缺少對物理獨立性的考慮。

    以Yii框架為例子來說,Yii框架的組織結構大致如下所示:

           Site

                |____resources

                |____protected

                        |____config

                        |____controllers

                        |____models

                        |____views

                        |____components

                |____framework

                |____index.php

        

    resources代表站點的一些資源性資料,如圖片、樣式表等。freamework為框架核心檔。index.php為入口文件,所有訪問路徑均以index.php后跟參數(shù)為標準。而protected內就是業(yè)務邏輯需要的MVC三層及系統(tǒng)需要的一些配置信息了。protected內的componets下是系統(tǒng)的組件類,如果有與系統(tǒng)業(yè)務流程無關,但是在業(yè)務邏輯中需要的函數(shù)庫,可以將它們作為組件放到這個目錄下,如果配置文件內注冊了該組件,在系統(tǒng)運行時會產(chǎn)生它們的實例以供調用。執(zhí)行的流程大致如下圖所示:

PHP框架的三層架構設計真的合適么?

PHP框架的三層架構設計真的合適么?

    根據(jù)上圖可以看出,Action需要同時與Model層與View層進行交互,在Action內,不僅有業(yè)務邏輯,還需調用Model層的方法和View層的方法。這樣,業(yè)務邏輯與Model層、View層就存在了緊耦合的關系。這種層次結構應用在基本的網(wǎng)站上還是可以滿足要求,但是不具備擴展性和可修改性。如果現(xiàn)在想把業(yè)務邏輯包裝稱REST風格或SOAP服務,那么只能重新寫一次包含業(yè)務邏輯的Action,因為現(xiàn)在的Action里已經(jīng)包含了頁面的輸出方法,而不是單純的數(shù)據(jù)結果。對于需要使用同一動態(tài)數(shù)據(jù)展示不同表現(xiàn)形式的需求,也只能通過判斷(修改)的方式而不能通過增加類或簡單Action(擴展)的方式實現(xiàn)。這違反了面向對象的開放封閉原則。由于系統(tǒng)需求往往是頻繁的變更的,如果我們常常的修改現(xiàn)有的代碼,不僅會造成現(xiàn)有系統(tǒng)代碼結構的混亂,而且極易造成隱藏的,難以發(fā)現(xiàn)的錯誤。所以,只有通過擴展來實現(xiàn)需求的變更,對系統(tǒng)來說才是最安全的。我們的工作才會更加的輕松和高效。

    既然Yii提供的源碼不能完美的解決擴展性和可修改性的問題,那么我們何不對它進行一次小小的改造,使它能勝任更加高的要求呢。俗話說的好,在軟件的世界里,加一層能解決所有的問題。所以,我們也決定使用“加一層”的辦法,以提高我們系統(tǒng)的可擴展性與可修改性。由于Yii是通過URI路由來查找Action并進行相應操作,最后也是通過Action方法產(chǎn)生響應結果的。所以,為了不破壞Yii的框架結構,我們只能在Action的下方增加一層,作為專門的業(yè)務邏輯層。為了偷懶,我們借鑒Java的叫法,稱它為bean層。此時,Action就最為一個專門的包裝層,包裝bean的邏輯,然后與View層交互產(chǎn)生頁面,或直接輸出數(shù)據(jù)。這樣如果我想把業(yè)務流程包裝成SOAP服務,只需增加一個Action即可,無需重寫業(yè)務邏輯。如果有多種視圖顯示要求,也無須重寫業(yè)務邏輯,只需擴展Action即可。下面用代碼來說明“這一層”是如何加上去的。

    首先我們在protected目錄下新建一個beans目錄,然后在components內新建LoadBean.php文件,用于實例化bean類及獲取bean對象。beans下的文件以XXXBean.php命名,如SiteBean.php。在beans下新建一個configure.php文件。此文件是bean加載的配置文件,以實現(xiàn)IOC之用。新結構如下所示:

           Site

                |____resources

                |____protected

                        |____config

                        |____controllers

                        |____models

                        |____views

                        |____beans

                                |____configure.php

                                |____SiteBean.php

                        |____components

                                |____LoadBean.php

                |____framework

                |____index.php

        

    beans下是專門負責業(yè)務邏輯的地方,Action內只需調用beans下的業(yè)務邏輯并提供輸出即可,無需再寫業(yè)務邏輯代碼。為了達到以上要求,我們需要對Yii的代碼做少許修改。首先找到框架核心內的CWebApplication.php文件,它的位置是framework/web/CWebApplication.php。 在該文件內添加一個getBeanPath與一個reloadBeans方法。代碼如下:

 public function getBeanPath(){
  return $this->_controllerPath=$this->getBasePath().DIRECTORY_SEPARATOR.'beans';
 }
 public function reloadBeans(){
  $beanPath = $this->getBeanPath();
  if(is_dir($beanPath)){
   $current_dir =opendir($beanPath);
   while(($file = readdir($current_dir))!==false){
    if($file=='.' OR $file=='..')
     continue;
    require($beanPath.DIRECTORY_SEPARATOR.$file);
   }
  }
 }

    然后找到該文件內的runController方法,在runController方法的開頭處調用reloadBeans方法:

        

 public function runController($route)
 {
  $this->reloadBeans();
  if(($ca=$this->createController($route))!==null)
  {
   list($controller,$actionID)=$ca;
   $oldController=$this->_controller;
   $this->_controller=$controller;
   $controller->init();
   $controller->run($actionID);
   $this->_controller=$oldController;
  }
  else
   throw new CHttpException(404,Yii::t('yii','Unable to resolve the request "{route}".',
    array('{route}'=>$route===''?$this->defaultController:$route)));
 }

    第三步,打開剛才新建的LoadBean.php文件,添加以下代碼:

class LoadBean {
 private $objs;
 public function init(){
  $beanconfig = Yii::app()->basePath.'\beans\configure.php';
  $beans = require $beanconfig;
  foreach($beans as $bean){
   if (!$this->objs[$bean] instanceof $bean.'Bean'){
    $class = $bean.'Bean';
    if(class_exists($class)){
     $this->objs[$bean] = new $class($bean);
    }
   }
  }
 }
 public function obj($name){
  try{
   if (array_key_exists($name,$this->objs)){
    return $this->objs[$name];
   }else{
    throw new Exception('bean name error');
   }
  }catch(Exception $e){
   echo $e->getMessage();
  }
 }
}

    第四步,找到protected/config/main.php文件,添加以下代碼:

  'beans'=>array(
   'class'=>'LoadBean',
  ),

讓系統(tǒng)在初始化時加載第三步添加的LoadBean類。

    

    第五步,找到protected/beans/SiteBean.php,添加以下代碼:

class SiteBean extends Controller{
 public function abc(){
      return123;
 }
}

此abc方法即是我們的業(yè)務邏輯代碼。

        

    第六步,找到protected/beans/configure.php,添加以下代碼:

 return array(
  'Site',
  );

此'Site'即為SiteBean類的'Site'名。

    

    第七步,實現(xiàn)Action方法,找到protected/controllers/SiteController.php文件(如沒有,可直接創(chuàng)建),代碼如下:

class SiteController extends Controller{
     public function actionIndex(){
          print_r(Yii::app()->beans->obj('Site')->abc());
     }
}

Action類不直接與Bean類交互,而是通過組件類做代理進行通訊,使Action與Bean也實現(xiàn)了分離。

    此時,利用瀏覽器訪問http://yourdomain/index.php?r=Site/index,即可顯示123。在此,我們實現(xiàn)了業(yè)務邏輯與Action的分離,增加了系統(tǒng)的擴展性與可修改性,bean實現(xiàn)了物理部署獨立。形成了我們的四層架構。

        

PHP框架的三層架構設計真的合適么?

PHP框架的三層架構設計真的合適么?

本文標題:PHP框架的三層架構設計真的合適么?
分享URL:http://muchs.cn/article8/pdjeop.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站制作企業(yè)建站、網(wǎng)站營銷建站公司、云服務器、關鍵詞優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

h5響應式網(wǎng)站建設