답변:
MVC
컨트롤러 : 사용자가 원하는 것을 해결하고, 무엇을 줄 것인지, 로그인했는지, 특정 데이터를 볼 수 있는지 등을 결정하는 것과 관련된 코드를 여기에 넣으십시오. 결국 컨트롤러는 요청을 봅니다. 표시 할 데이터 (모델)와 렌더링 할 뷰를 계산합니다. 코드가 컨트롤러에 들어가야하는지 확실하지 않다면 아마 그렇지 않을 것입니다. 컨트롤러를 마른 상태로 유지하십시오 .
보기 :보기에는 데이터 (모델)를 표시하기위한 최소 코드 만 포함되어야하며, 많은 처리 또는 계산을 수행해서는 안되며, 모델에서 계산하거나 요약 한 데이터를 표시하거나 컨트롤러에서 생성 한 데이터를 표시해야합니다. 뷰가 실제로 모델 또는 컨트롤러로 수행 할 수없는 처리를 수행 해야하는 경우 코드를 도우미에 넣으십시오. 뷰에 많은 루비 코드가있어 페이지 마크 업을 읽기가 어렵습니다.
모델 : 모델은 데이터와 관련된 모든 코드 (사이트를 구성하는 엔티티 (예 : 사용자, 게시물, 계정, 친구 등)) 가있는 곳이어야합니다 . 코드가 엔티티와 관련된 데이터를 저장, 업데이트 또는 요약해야하는 경우 여기에 입력하십시오. 뷰와 컨트롤러에서 재사용 할 수 있습니다.
pauliephonic의 답변에 추가하려면 :
도우미 :보기를보다 쉽게 만들 수있는 기능입니다. 예를 들어, 가격을 표시하기 위해 항상 위젯 목록을 반복하는 경우 실제 표시의 일부와 함께 도우미에 배치하십시오. 또는보기를 어지럽히고 싶지 않은 RJS 조각이 있으면 도우미에 넣으십시오.
MVC 패턴은 실제로 UI에만 관련이 있습니다. 컨트롤러는 뷰를 제어하지만 로직은 제어하지 않으므로 복잡한 비즈니스 로직을 컨트롤러에 넣지 마십시오. Controller는 적절한보기를 선택하고 도메인 모델 (모델) 또는 비즈니스 계층에보다 복잡한 항목을 위임하는 데 관심을 가져야합니다.
Domain Driven Design에는 서비스 개념이 있으며, 이는 여러 종류의 객체를 오케스트레이션해야하는 로직이며, 일반적으로 Model 클래스에 속하지 않는 로직을 의미합니다.
나는 일반적으로 서비스 계층을 내 응용 프로그램의 API로 생각합니다. 내 서비스 계층은 일반적으로 내가 만드는 응용 프로그램의 요구 사항과 매우 밀접하게 매핑되므로 서비스 계층은 내 앱의 하위 수준에서 발견되는 더 복잡한 상호 작용을 단순화하는 역할을합니다. 즉, 서비스 계층을 우회하는 동일한 목표를 달성 할 수 있습니다 하지만 작동하려면 더 많은 레버를 당겨야합니다.
나는 여기서 Rails에 대해 이야기하지 않고 특정 문제를 해결하는 일반적인 건축 스타일에 대해 이야기하고 있습니다.
여기에 대한 완벽한 설명, 결론과 기억하기 쉬운 간단한 문장 하나가 있습니다.
SMART 모델, THIN 컨트롤러 및 DUMB 뷰가 필요합니다.
Rails 방식은 스키니 컨트롤러와 팻 모델을 사용하는 것 입니다.
인증 / 액세스 제어와 관련된 것을 컨트롤러에 넣습니다.
모델은 모든 데이터에 관한 것입니다. 검증, 관계, CRUD, 비즈니스 로직
조회수는 데이터를 표시하는 것입니다. 표시 및 입력 만.
컨트롤러는 모델에서 뷰로 이동하는 데이터와 뷰에서 모델로 이동하는 데이터를 제어하는 것입니다. 컨트롤러는 모델 없이도 존재할 수 있습니다.
나는 컨트롤러를 경비원 / 수신자라고 생각합니다. 고객 (요청)을 고객에게 요청하는 적절한 카운터로 안내합니다 (보기). 그러면 텔러 (보기)는 관리자 (모델)로부터 답변을 얻습니다. 그런 다음 요청은 경비원 / 수신자 (컨트롤러)로 돌아가서 다른 텔러 (보기)에게 갈 때까지 기다립니다. 다른 텔러 (보기)는 관리자 (모델)가 다른 텔러 (보기) 질문에 대한 답변을 알려줍니다. .
마찬가지로 텔러 (보기)에게 무언가를 말하고 싶다면 두 번째 텔러가 관리자가 귀하의 정보를 수락했는지 여부를 알려주는 것을 제외하고는 거의 동일한 일이 발생합니다. 관리자에게 해당 정보를 알려줄 권한이 없기 때문에 경비원 / 수신자 (컨트롤러)가 하이킹을하도록 지시했을 수도 있습니다.
비유적이고 비현실적인 세상에서 은유를 확장하기 위해, 텔러 (조회)는 예쁘지 만 머리가 비어 있고 종종 당신이 말하는 것을 믿습니다. 가지 말고 관리자는 정말 추악하고 의미가 있지만 모든 것을 알고 무엇이 진실인지 아닌지를 말할 수 있습니다.
적절하게 분리하는 데 도움이되는 한 가지는 "컨트롤러에서 로컬 변수를 전달하여"반 패턴을 피하는 것입니다. 이 대신에 :
# app/controllers/foos_controller.rb:
class FoosController < ApplicationController
def show
@foo = Foo.find(...)
end
end
#app/views/foos/show.html.erb:
...
<%= @foo.bar %>
...
도우미 메소드로 사용 가능한 게터로 이동하십시오.
# app/controllers/foos_controller.rb:
class FoosController < ApplicationController
helper_method :foo
def show
end
protected
def foo
@foo ||= Foo.find(...)
end
end
#app/views/foos/show.html.erb:
...
<%= foo.bar %>
...
이렇게하면 "@foo"에 넣은 내용과 사용 방법을보다 쉽게 수정할 수 있습니다. 컨트롤러와 뷰를 더 복잡하게 만들지 않고 분리합니다.
foo
및이 @foo
동일 - 이들은 모두 <ControllerClass 요청> 쌍 범위가된다. 또한 getter 버전을 사용 Foo
하여 뷰가 액세스하는 방식을 변경하지 않고 해당 객체를 찾거나 저장 / 캐시하는 방법을 변경할 수 있습니다.
글쎄, 그것은 논리가 처리해야 할 것에 달려 있습니다.
종종 더 많은 것을 모델로 밀어 넣어 컨트롤러를 작게 유지하는 것이 좋습니다. 이를 통해 모델이 나타내는 데이터에 액세스해야하는 모든 위치에서이 논리를 쉽게 사용할 수 있습니다. 뷰에는 로직이 거의 없어야합니다. 따라서 실제로는 일반적으로 반복하지 않도록 노력해야합니다.
또한 구글의 간단한 정보는 어디로 가는지 몇 가지 더 구체적인 예를 보여줍니다.
모델 : 검증 요구 사항, 데이터 관계, 메소드 작성, 메소드 업데이트, 메소드 제거, 메소드 찾기 (이 메소드의 일반 버전뿐만 아니라 빨간색을 가진 사람을 찾는 것과 같이 많은 일을하는 경우) 성을 기준으로 한 머리를 찾은 다음 find_redH_by_name ( "smith") 또는 이와 유사한 이름을 호출하기 만하면 해당 논리를 추출해야합니다.
보기 : 이것은 데이터 처리가 아니라 데이터 형식에 관한 것이어야합니다.
컨트롤러 : 데이터 처리가 진행됩니다. 인터넷에서 : "컨트롤러의 목적은 사용자가 요청한 조치에 응답하고, 사용자가 설정 한 모든 매개 변수를 취하고, 데이터를 처리하고, 모델과 상호 작용 한 다음, 요청 된 데이터를 최종 양식으로 전달하는 것입니다. 전망."
희망이 도움이됩니다.
테스팅, 테스팅 ... 모델에 최대한 많은 로직을 넣으면 제대로 테스트 할 수 있습니다. 단위 테스트는 모델 테스트를 통해 데이터와 데이터의 구성 방식을 테스트하고 기능 테스트는 컨트롤러를 테스트하여 라우팅되거나 제어되는 방식을 테스트하므로 데이터가없는 한 데이터 무결성을 테스트 할 수 없습니다. 모델.
제이