2014-09-06 36 views
1

所以我使用Laravel作爲我的網站,但是我在判斷代碼的結構時遇到了困難,所以我希望對我的結構的有效性提供一些意見。負責分離職責php對於控制器

我當然使用通過控制器路由,請求進來,這是路由到Processor,這個處理器還接收處理器用來再次路由的監聽器(控制器)。一個例子

class PageController{ 
    public function __construct(PageProcessor $pageProcessor) 
    { 
     $this->processor = $pageProcessor; 
    } 
    public function edit($id = null) 
    { 
     $this->processor->edit($this, $id); 
    } 
    public function editFailed($message) 
    { 
     return View::make('edit.failed', $message); 
    } 
    public function editSucceed($data) 
    { 
     return View::make('edit.succeed', $data); 
    } 
} 
class PageProcessor{ 
    public function __construct(PageRepository $pageRepository, PageValidator $pageValidator) 
    { 
     $this->repository = $pageRepository; 
     $this->validator = $pageValidator; 
    } 
    public function edit($id = null) 
    { 
     // logic for showing the edit page 
     // 
     // more logic 

     if($logicSucceeded) 
     { 
      return $listener->editSucceed(compact('page', 'awesomeData')); 
     } 
     else 
     { 
      return $listener->editFailed('something failed'); 
     } 
    } 

} 

現在我的問題是與控制器的傳遞到處理器,那種違背職責的分離,但我想不出這樣做的另一種方式。

總結:保持相互糾纏的班級職責的最佳方式是什麼?

怎樣纔可以有一個使用另一個不知道它是如何工作...

回答

3

在我看來,有可能會顯示在頁面處理器的編輯頁面可以讓你在某些時候混合reponsibilities邏輯。從這裏看你的代碼非常好,控制器和控制器之外的業務邏輯很瘦。但我把意見回控制器:

class PageController { 

    public function __construct(PageProcessor $pageProcessor) 
    { 
     $this->processor = $pageProcessor; 
    } 

    public function edit($id) 
    { 
     $this->processor->validate($id, Input::all()); 

     $data = $this->processor->getEditData($id); 

     return View::make('edit', compact('data')); 
    } 

    public function update($id) 
    { 
     $this->processor->update($data); 

     // If the update fails, an exception will be thrown and it will never reach this return 

     return Redirect::back(); 
    } 

    public function editFailed($message) 
    { 
     return View::make('edit.failed', $message); 
    } 

    public function editSucceed($data) 
    { 
     return View::make('edit.succeed', $data); 
    } 
} 

處理器將只負責數據處理和投擲的錯誤消息:

class PageProcessor { 

    public function __construct(PageRepository $pageRepository, PageValidator $pageValidator) 
    { 
     $this->repository = $pageRepository; 
     $this->validator = $pageValidator; 
    } 

    public function getEditData($id) 
    { 
     return $this->repository->getData($id); 
    } 

    public function update($data) 
    { 
     if($updatedModel = $this->repository->update($data['id'], $data)) 
     { 
      $listener->editSucceed(compact('page', 'awesomeData')); 

      throw new Exception("Error Updating Model"); 
     } 

     $listener->editFailed('something failed'); 

     return $updatedModel; 
    } 

    public function validate($id, $input) 
    { 
     if ($this->repository->validation->fails($id, $input)) 
     { 
      throw new Exception("Validation failed", $this->repository->validation->errors()); 
     } 

     return true; 
    } 
} 

有一個consesus該驗證應在控制器中觸發,甚至在它之前,就像在Laravel 4.3中一樣,所以我也將它添加到控制器方法中。

編輯:

共識之處在於在處理用戶輸入的是控制器的責任。當然,有時候不僅僅知道電子郵件是否形成良好,有時您的業務邏輯取決於其他因素,但現在我們正在談論兩種不同類型的驗證:輸入數據和業務數據。在meta中有一個很好的解釋:https://softwareengineering.stackexchange.com/questions/97880/in-mvc-should-a-model-handle-validation

在Laravel 4.3輸入數據會被你的控制器實際上在控制器實例進行處理,:

所以你會看到正在做這樣的控制器:

public function store(AddOfficeRequest $request) 
{ 
    $this->execute(AddOfficeCommand::class, $input); 

    Flash::message('Office created'); 

    return Redirect::back(); 
} 

AddOfficeRequest

use use Illuminate\Foundation\Http\FormRequest; 

class AddOfficeRequest extends FormRequest { 

    public function rules() 
    { 
     return [ 
      'name' => 'required', 
      'contact' => 'required', 
      'email' => 'required|email', 
     ]; 
    } 

} 

而這樣的結果是你的控制器store方法只被打if輸入驗證通過,否則Laravel將自動地Redirect::back()->withInput()->withErrors()

+0

在控制器驗證只是看起來像褻瀆,是不是應該是業務邏輯?我的處理器是將驗證和模型結合在一起的處理器,例如創建表格。您可以詳細說明他在控制器中的驗證嗎?> – WiseStrawberry 2014-09-07 17:11:03

+1

已編輯進行詳細說明。 – 2014-09-07 17:33:58

+0

啊....將不得不潛入laravel 4.3下一個項目。 – WiseStrawberry 2014-09-07 17:42:49

1

OOP的規則並不像我想的那樣嚴格。是的,職責分離需要創建可普遍化的類,這是將一些邏輯分解到自己的類中的一個原因。

但是,例如你可能已寫入PageControllerPageProcessor邏輯裏面。也許這只是笨拙的代碼。創建任何數量的具有特定職責的職業也不是什麼壞事,這些職責只能在另一個職業中引用 - 特別是如果您認爲將來可能會被另一個職業使用PageProcessor