2

MVC에서 내 이해에 따르면, 논리는 모델에 상주하며 컨트롤러는 조정 부분을 처리하며 보기가 데이터 표현을 위해 존재합니다.로직을 컨트롤러에 유지하는 대신 모델로 푸시하는 방법은 무엇입니까?

다음은 컨트롤러에서 추출한 코드입니다. PHP 프레임 워크 인 codeigniter로 작성되었습니다. 아래에서 발생하는 상황은 이미지를 사용할 수있는 경우 삭제됩니다. 그렇지 않으면 사용자가 이미지 양식을 삭제하도록 리디렉션됩니다.

if($this->records_model->check_img_availability($img_data)) 
{ 
    //delete if the image is available 
    $this->records_model->delete_img($img_data); 
} 
else 
{ 
    //redirected to delete image form 
    $this->session->set_flashdata('errormsg', 'Img is not available'); 
    redirect(base_url() . 'records/deleteimg/'); 
} 

로직이 컨트롤러에 있으므로 위의 MVC는 잘못되었습니다. 이미지가 삭제되는지 아니면 사용자가 리디렉션되는지에 따라 이미지를 사용할 수 있는지 여부를 확인합니다.

논리를 컨트롤러에 유지하는 대신 모델로 푸시하는 방법은 무엇입니까?

답변

4

서비스 계층을 사용하십시오. 이제 컨트롤러에있는 논리가 하나의 서비스로 이동합니다.

서비스는 일반적으로 관련 응용 프로그램 논리의 큰 부분을 처리합니다.

예를 들어, 응용 프로그램이 제품을 판매 한 경우 장바구니의 기능/논리 및 고객 체크 아웃이 어딘가에 있어야합니다. 기능이 비슷하기 때문에 당신은 Services\Shopping 클래스로 모든 관련 논리를 밀어 것입니다 그것은 다음과 같은 API 수 :

interface Shopping { 

    /** 
    * @param int $productId 
    * @param int $quantity 
    * @return bool 
    */ 
    public function addToCart($productId, $quantity); 

    /** 
    * @param int $productId 
    * @return bool 
    */ 
    public function removeItem($productId); 

    /** 
    * @param int $productId 
    * @param int $quantity 
    * @return bool 
    */ 
    public function updateQuantity($productId, $quantity); 

    /** 
    * Customer checkout. 
    * 
    * @param string $firstName 
    * @param string $lastName 
    * @param string $emailAddress 
    * @return bool 
    */ 
    public function checkout($firstName, $lastName, $emailAddress, .....etc); 

} 

서비스로 당신은 기본적으로 그냥 그룹과 유사한 모델의 레이어 기능과 서비스에게 좋은 이름을 어떤 종류의 작업/기능이 수행되는지를 광범위하게 설명합니다.

이제 컨트롤러가 요청에서 데이터를 추출하여 서비스로 보내 작업을 수행 할 수 있습니다.

일부 컨트롤러 메소드

는 쇼핑 카트에 항목을 추가합니다 :

$productId = (int)$this->request->post('productId'); 
$quantity = (int)$this->request->post('quantity'); 

// Now send the data to the shopping service to do the work. 
$this->shopping->addToCart($productId, $quantity); 

은 이제 컨트롤러는 마른 체형과 논리의 자유가 될 수 있습니다. 서비스를 구현하는 방법은 귀하에게 달려 있습니다. 서비스는 다른 서비스에 의존하여 모델 계층의 여러 기능과 상호 작용할 수 있습니다.

편집 시나리오를 들면 나는 이미지 등 관련이 제가 이미지를 삭제하는 이유에 대한 충분한 정보를 잘 모릅니다 때문에 서비스에 대한 설명이 포함 된 이름과 함께 올 수없는

그래서 난 그냥 것 Services\Image으로 전화하십시오. 이것은 너무 구체적이기 때문에 서비스의 나쁜 이름으로 간주 될 수 있지만 데모 목적으로 만 사용됩니다.

class Image extends AbstractService { 

    /** 
     * This is assuming you have an ID for a row in the database containing data 
     * about the image like the path to the image so it can be deleted from the server. 
     * 
     * @param int $id 
     * @return bool 
     */ 
    public function delete($id) { 

     $mapper = $this->mapperFactory->build('Image'); 
     $image = $mapper->fetch($id); 

     if($image === null) { 
      return $this->fail('Image does not exist.'); 
     } 

     try { 
      $mapper->delete($image); // Delete the image row in the database. 
      unlink($image->getPath()); // Delete the image file from the server. 

      return $this->success('Image deleted successfully.'); 
     } 
     catch(\RuntimeException $ex) { 
      return $this->fail('Failed to delete the image.'); 
     } 
    } 

} 

success()fail 방법은 부모의 서비스에 있습니다. 모델 레이어의 상태를 업데이트하고 필요한 경우 사용자에게 표시 할 메시지를 설정합니다. 메서드 failed()은 자식 서비스에서 $this->fail()을 호출 한 경우 true를 반환하는 부모 AbstractService에서 온 것입니다.당신이보기 두뇌를 가지고 있으며, 로직을 수행 할 수 있습니다 볼 수 있듯이

if($this->imageService->hasState()) { 
    if($this->imageService->failed()) { 
     // If deleting the image failed do whatever you want here. 
     // Switch templates, redirect or whatever. 
    } 
    else { 
     // The image was deleted successfully so do whatever you want here. 
     // Again, switch templates, redirect or whatever. 
    } 
    // Bind the message to the template. 
} 

:

다음보기에 당신이 뭔가를 할 수 있습니다. 이것은 CI가 나쁜 영역입니다. 뷰는 기본적으로 두뇌가없는 템플릿이므로보기에 있어야하는 논리가 컨트롤러, 서비스 계층 등에 푸시됩니다.

기본적으로 컨트롤러는 delete($id) 메서드를 통해 이미지 서비스와 통신하며 해당 메서드는 이미지를 삭제하고 모델 레이어의 상태를 설정하면 뷰는 이미지 서비스와 대화하고 어떤 종류의 상태인지 묻고 모델 레이어의 상태를 기반으로해야 할 논리를 수행합니다.

내 의견으로는 서비스는 일반적으로 응답 또는 리디렉션을 보내는 방법을 알지 않아야합니다. 이것이보기 책임입니다.

Symfony는 아마도 가장 좋은 PHP 프레임 워크 일 것이지만 많은 사람들이 가장 가파른 학습 곡선을 가지고 있다고 말합니다. 동의하지 않은 것을보기 시작할 때까지 설명서에 몇 페이지를 추가하여 탐색을 중단하기로 결정했습니다.

PHP 작성자 인 Rasmus Lerdorf는 모든 PHP 프레임 워크가 끔찍하다고 말합니다.

행운을 빈다.

+0

답변에 따르면 MVCS이고 S는 서비스를 의미합니다. 컨트롤러는 모델 또는 서비스 레이어와 통신합니까? – Techie

+1

컨트롤러는 서비스와 통신합니다. 서비스는 모델 계층 위에 위치합니다. 서비스는 모델 레이어에 대한 게이트웨이와 같습니다. Codeigniter는 잘못 설계된 프레임 워크이며 컨트롤러는 너무 많은 책임을지는 god 객체와 비슷하기 때문에 컨트롤러에서 부하를 제거하고 그 안에있는 논리를 서비스로 밀어 넣는 것이 좋습니다. 서비스는 도메인 개체와 데이터 매퍼가 포함 된 잘 정의 된 모델 계층이있을 때 사용하기 쉽습니다. CI는 컨트롤러에서 도메인 객체 (모델이라고 부르는 모델)로 작업하기를 좋아하지만 이는 서비스에서 수행해야합니다. – ibanore

+0

CI가 잘못 설계 되었다면 어느 프레임 워크가 좋다고 생각합니까? 가능한 경우 모든 세부 사항으로 답을 편집하십시오. 다른 사람들에게도 도움이 될 것입니다. – Techie