2014-09-06 1 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'); 
     } 
    } 

} 

내 문제는 가지 책임의 분리를 패배,하지만 난이 일을 다른 방법을 생각하지 못할, 프로세서 컨트롤러의 통과와 함께입니다.

요약 : 서로 얽혀있는 클래스의 책임을 지키는 가장 좋은 방법은 무엇입니까?

어떻게 당신이 어떤 점에서 reponsibilities를 혼합 할 수있는 페이지 프로세서에서 편집 페이지를 표시하기위한 논리를 가지고, 다른 그것이 어떻게 작동하는지 알 수없는 한 사용 ... 제 생각에는

답변

3

을 가질 수 있습니다. 여기에서 코드를 보면 컨트롤러 외부의 마른 컨트롤러와 비즈니스 로직이 매우 좋습니다. 하지만 컨트롤러에 다시보기를 가져올 것입니다 : 검증이 컨트롤러 트리거해야하는 consesus가있다

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; 
    } 
} 

:

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); 
    } 
} 

프로세서는 데이터 처리 및 던지는 오류 메시지에 대한 책임을 질 것입니다 , 또는 Laravel 4.3에서와 같이 이전에, 컨트롤러 메소드에도 추가했습니다.

EDIT :

합의 사용자 입력을 처리하는 제어기의 책임이 있다는 사실에있다. 물론 때로는 이메일이 잘 형성되었는지, 비즈니스 로직이 다른 요인에 의해 좌우되는지를 아는 것 이상의 의미가 있지만 지금은 입력 데이터와 비즈니스 데이터라는 두 가지 유형의 검증에 대해 이야기하고 있습니다. 메타에 대한 좋은 설명이 있습니다 : https://softwareengineering.stackexchange.com/questions/97880/in-mvc-should-a-model-handle-validation.

4.3 입력 데이터가 실제로 컨트롤러 인스턴스화하는 동안, 당신의 컨트롤러에서 처리됩니다 Laravel에서

:

그래서 컨트롤러는 다음과 같이 이루어지고 볼 수 있습니다 : AddOfficeRequest 될 것

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

    Flash::message('Office created'); 

    return Redirect::back(); 
} 

그건

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

+1

정교하게 편집되었습니다. –

+0

아 .... Laravel 4.3 프로젝트로 뛰어 들어야 할 것입니다. – WiseStrawberry

1

OOP의 규칙은 당신이 생각하는대로 엄격하게 작성하는 것이 아닙니다. 예, 책임의 분리는 일반화 가능한 클래스를 작성해야하며, 이는 일부 논리를 자체 클래스로 분리하는 한 가지 이유입니다.

예를 들어 은 이고 PageProcessor 로직은 내부에이 글 수 있습니다. 아마 그것은 다루기 힘든 코드 일 것입니다.특정 책임을 지닌 클래스 수를 만드는 것은 나쁜 일이 아닙니다. 특히 다른 클래스에서 PageProcessor을 사용할 수 있다고 생각하는 경우에만 다른 클래스에서 참조됩니다.