Model-View-Controller 패턴에서 모델과 뷰의 역할을 이해하지만 컨트롤러가 왜 필요한지 이해하기가 어렵습니다.
MVC 방식을 사용하여 체스 프로그램을 작성한다고 가정 해 봅시다. 게임 상태는 모델이어야하고 GUI는보기 여야합니다. 이 경우 컨트롤러는 정확히 무엇입니까?
타일을 클릭 할 때 호출되는 모든 기능을 가진 별도의 클래스입니까? 뷰 자체에서 모델의 모든 로직을 수행하는 것이 어떻습니까?
Model-View-Controller 패턴에서 모델과 뷰의 역할을 이해하지만 컨트롤러가 왜 필요한지 이해하기가 어렵습니다.
MVC 방식을 사용하여 체스 프로그램을 작성한다고 가정 해 봅시다. 게임 상태는 모델이어야하고 GUI는보기 여야합니다. 이 경우 컨트롤러는 정확히 무엇입니까?
타일을 클릭 할 때 호출되는 모든 기능을 가진 별도의 클래스입니까? 뷰 자체에서 모델의 모든 로직을 수행하는 것이 어떻습니까?
답변:
귀하의 예를 사용하면 컨트롤러가 합법적 인 행동인지 아닌지를 결정하게 될 것입니다. 컨트롤러는 모델로부터받은 정보를 사용하여 시작시 보드의 조각을 배열하는 방법을보기에 알려줍니다. Controller가 처리 할 수있는 작업이 더 있지만 핵심은 해당 계층의 Business Logic에 대해 생각하는 것입니다.
모든 컨트롤러가 가입 페이지처럼 정보를 앞뒤로 전달하는 경우가 있습니다. 다른 경우에는 규칙 시행이나 복잡한 수학과 같이 해당 계층에서 수행해야 할 일이 많기 때문에 Controller는 개발의 어려운 부분입니다. 컨트롤러를 잊지 마십시오!
뷰 자체에서 모델의 모든 로직을 수행하는 것이 어떻습니까?
컨트롤러는 모델과 뷰를 묶는 접착제이며,이를 분리하는 단열재이기도합니다. 모델은 뷰에 대해 아무것도 알지 않아야하며 그 반대도 마찬가지입니다 (적어도 Apple의 MVC 버전에서는). 컨트롤러는보기에서 사용자 조치를 메시지로 모델로 변환하고 모델의 데이터로보기를 구성하는 양방향 어댑터처럼 작동합니다.
컨트롤러를 사용하여 모델과 뷰를 분리하면 코드를 더욱 재사용 가능하고 테스트 가능하며 유연하게 만들 수 있습니다. 체스 예제를 고려하십시오. 모델에는 물론 게임 상태가 포함되지만, 이동이 합법적인지 여부를 결정하고 게임이 종료 될 때를 결정하는 등 게임 상태의 변경에 영향을 미치는 논리도 포함 할 수 있습니다. 뷰는 체스 판과 조각을 표시하고 조각이 움직일 때 메시지를 보내지 만 조각의 의미, 조각이 어떻게 움직이는 지 등은 알지 못합니다. 프로그램의 전반적인 흐름. 사용자가 '새 게임'버튼을 누르면, 모델에게 게임을 만들도록 지시하고 새 게임의 상태를 사용하여 보드를 설정하는 컨트롤러입니다. 사용자가 이동하면
모델과 뷰를 별도로 유지하여 얻은 것을 살펴보십시오.
다른 모델을 변경하지 않고 모델이나 뷰를 변경할 수 있습니다. 컨트롤러를 변경하면 컨트롤러를 업데이트해야 할 수도 있지만, 이것이 이점의 일부입니다. 변경 가능성이 가장 높은 프로그램 부분이 컨트롤러에 집중되어 있습니다.
모델과 뷰를 모두 재사용 할 수 있습니다. 예를 들어 유명한 게임을 설명하기 위해 RSS 피드와 동일한 체스 판보기를 모델로 사용할 수 있습니다. 또는 동일한 모델을 사용하고보기를 웹 기반 인터페이스로 바꿀 수 있습니다.
모델과 뷰 모두에 대해 테스트를 작성하여 원하는대로 작동하는지 쉽게 확인할 수 있습니다.
모델과 뷰는 종종 표준 부품 (모델의 배열, 맵, 세트, 문자열 및 기타 데이터 컨테이너)을 이용할 수 있습니다. 버튼, 컨트롤, 텍스트 필드, 이미지 뷰, 테이블 및 기타 뷰.
이 일반적인 디자인 패턴을 구현하는 방법은 여러 가지가 있지만 기본 아이디어는 필요에 따라 다양한 관심사를 분리하는 것입니다. MVC는 다음과 같은 점에서 좋은 추상화입니다.
모델 :는 그 의미 할 수 있습니다 어떤 데이터가
보기 나타냅니다 사용자 인터페이스, 즉 의미 할 수 있습니다 무엇 :
컨트롤러 : 대표에게 접착제를 원인 모델과 상호 작용에보기, 즉 무엇을 의미 할 수 있다는 것을
전체를 많이 지정하지 않기 때문에 매우 유연합니다. 많은 사람들이 각 요소가 무엇을 의미하는지, 이들 대신 어떤 이름을 사용해야하는지, 그리고 실제로 3 개, 2 개 또는 4 개 또는 5 개의 구성 요소가 있어야하는지에 대한 세부 사항을 주장하면서 많은 대역폭을 낭비하고 있습니다. 어느 정도.
아이디어는 서로 다른 "청크"논리를 분리하여 서로 겹치지 않도록하는 것입니다. 프리젠 테이션 자료를 함께 보관하고, 데이터 자료를 함께 보관하고, 논리 자료를 함께 보관하고, 의사 소통 자료를 함께 보관하십시오. 기타 등등. 어느 정도까지는 이러한 관심 영역이 겹치지 않을수록 흥미로운 일을하기가 더 쉽습니다.
그게 당신이 정말로 걱정해야 할 전부입니다.
지금까지 모든 좋은 답변. 내 두 센트는 컨트롤러가 주로 무엇과 어디서와 같은 질문으로 구성되는 것으로 생각한다는 것입니다.
이 작은 스 니펫은 MVC가 전달하려는 추상화와 개념을 기억하려는 방법의 예입니다. 나의 세 가지 주요 사고 과정은 무엇, 어디서, 어떻게 진행됩니까?
언제 어디서 => 컨트롤러 방법 및시기 => 모델 및 뷰
본질적으로 내 컨트롤러 작업은 작고 컴팩트 한 경향이 있으며 읽을 때 때로는 시간 낭비처럼 보입니다. 면밀한 조사를 통해 교통 신호 담당자 역할을 수행하여 다양한 요청을 적절한 작업자에게 전달하지만 실제 작업은 수행하지 않습니다.
이벤트 핸들러를 다룰 때 실제로 작동하지만 뷰와 모델 간의 상호 작용을 처리하려면 컨트롤러가 필요합니다. 이상적으로 뷰가 모델에 대해 아무것도 알기를 원하지 않습니다. 생각해보십시오 .JSP가 모든 데이터베이스 호출을 직접 수행하도록 하시겠습니까? (로그인 조회와 같은 것이 아니라면) 뷰 렌더링 로직이 아닌 뷰가 데이터를 렌더링하고 비즈니스 로직이없는 경우에는 비즈니스 로직이 아닙니다.
GWT에서는 MVP와 더 명확하게 분리됩니다. 보기에는 비즈니스 로직이 없습니다 (올바르게 완료된 경우). 발표자는 컨트롤러 역할을하며 뷰에는 모델에 대한 지식이 없습니다. 모델 데이터는 단순히 뷰로 전달됩니다.
Model-View-Controller 패턴에서 모델과 뷰의 역할을 이해하지만 컨트롤러가 왜 필요한지 이해하기가 어렵습니다.
확실합니까? (적어도 원래 설명 된대로) 모델의 요점은 도메인 모델입니다. 보기는 도메인 모델을 사용자에게 표시해야합니다. 컨트롤러는 저수준 입력을 고수준 모델 말하기에 매핑해야합니다. 내가 추론 할 수있는 한, A) SRP의 높은 수준의 사용. B) 모델은 앱의 중요한 부분으로 간주되어 중요하지 않고 빠르게 변화하는 것을 유지하십시오. C) 쉽게 테스트 가능하고 스크립트 가능한 비즈니스 로직.
시각 장애인이 Chess 프로그램을 사용할 수있게하려면, 소리 버전과 키보드와 작동하는 컨트롤러로보기를 바꾸십시오. 메일로 게임을 추가하고 텍스트를 허용하는 컨트롤러를 추가한다고 가정하십시오. 게임의 넷 버전? 소켓에서 명령을받는 컨트롤러가 작업을 수행합니다. 멋진 3D 렌더링을 추가하십시오. 제로 모델 변경 필요 체스는 여전히 체스입니다.
입력을 모형 표현과 혼합하면 해당 기능이 손실됩니다. 갑자기 체스는 체스가 아니며, 키보드 또는 네트워크 연결을 가진 체스와 다른 마우스를 가진 체스입니다.
MVC는 멍청하다고 생각합니다. 특정 영역에서는 잘 작동하지만 개인적으로 작성한 웹 사이트조차도 mvc에 적합하지 않습니다. 프론트 엔드, 백엔드를 듣고 데이터베이스 엔드 나 다른 엔드 엔드를 듣지 못하는 이유가 있습니다.
IMO에는 API (백엔드)와 API (프론트 엔드)를 사용하는 앱이 있어야합니다. GET 요청 컨트롤러 (백엔드 API를 단순히 호출)와 HTML을 뷰로 호출 할 수 있다고 생각하지만 일반적으로 사람들이 순수한 HTML로 뷰에 대해 이야기하거나 백엔드 API 인 모델에 대해 이야기하는 것을 듣지 않습니다.
IMO의 모든 것은 견고한 API 여야합니다. 실제로 그들은 깨끗하고 잘 구축 된 것처럼 견고 할 필요는 없지만 내부는 비공개로 유지되어야하며 API의 앱 / 프론트 엔드 / 외부는 데이터베이스 연결을 말하거나 원시 쿼리를 수행 할 수 없습니다.
이제 코드 / 디자인에 풀이 포함되어 있다면. 체스 게임에서 GUI를 스키닝하기 위해 편집 할 수있는 마크 업이있는 경우 GUI는 좌표 / 입력을 수집하고 MovePiece (srcPosition, dstPostion)를 호출합니다. ) 및 모든 논리가 모델에 있는지 확인한 다음 MVC라고합니다. 그러나 나는 여전히 클래스와 API로 사물을 구성하고 모든 것을 만지는 부엌 싱크 클래스가 있는지 확인합니다 (모든 API는 모든 것을 알아야합니다).
정적 웹 페이지를 표시하는 브라우저를 생각해보십시오. 모델은 HTML입니다. 보기는 화면의 실제 결과입니다.
이제 JavaScript를 추가하십시오. 이것이 컨트롤러입니다. 사용자가 버튼을 클릭하거나 무언가를 드래그하면 이벤트가 JavaScript로 전송 될 때 수행 할 작업을 결정하고 기본 HTML (모델)을 변경하고 브라우저 / 렌더러는 이러한 변경 사항을 화면에 표시합니다 (보기).
다른 버튼을 클릭하고 이벤트가 일부 처리기 (컨트롤러)로 전송되어 추가 데이터 요청이 웹 서비스로 전송 될 수 있습니다. 그런 다음 결과가 HTML (모델)에 추가됩니다.
컨트롤러는 이벤트에 응답하고 모델의 내용과 화면 /보기의 내용을 제어합니다.
조금 뒤로 물러 서면 전체 브라우저를 View로, 서버를 Controller로, 데이터를 Model로 생각할 수 있습니다. 사용자가 서버 (제어기)로 보낸 이벤트를 브라우저에서 버튼을 클릭하면 HTML 페이지 (모델)로 자원을 모아서 표시하도록 브라우저로 다시 보냅니다 (보기).
서버에서 ASP, PHP 또는 Java 여부에 관계없이 'code'(컨트롤러)는 클릭 이벤트를 수신하고 데이터베이스 또는 문서 저장소 (모델)를 쿼리하고 HTML을 작성합니다. 서버 관점에서 모든 조치의 결과는 기본 데이터 저장소 (모델)의보기 (HTML)입니다. 그러나 클라이언트 관점에서 서버에 대한 요청 결과는 모델 (HTML)입니다.
HTML에서 JavaScript 또는 HTML에서 PHP를 혼란스럽게하더라도 Model, View, Controller는 여전히 존재합니다. 서버에 대한 요청과 서버로부터의 응답을 단순한 양방향 거리라고 생각하더라도 모델, 뷰 및 컨트롤러가 여전히 있습니다.
내 경험에 따르면 전통적인 데스크탑 mvc gui 프로그램에서 컨트롤러는 결국 스파게티가 표시됩니다. 대부분의 사람들은 컨트롤러 클래스를 배제하는 데 시간이 걸리지 않습니다.
4 명의 갱은 다음과 같이 말합니다.
스몰 토크 MVC의 디자인 패턴
[KP88] 클래스의 MVC (Model / View / Controller) 트라이어드는 Smalltalk-80에서 사용자 인터페이스를 구축하는 데 사용됩니다. MVC 내부의 디자인 패턴을 보면 "패턴"이라는 용어의 의미를 이해하는 데 도움이됩니다.
MVC는 세 종류의 객체로 구성됩니다. 모델은 응용 프로그램 객체이고,보기는 화면 표현이며 컨트롤러는 사용자 인터페이스가 사용자 입력에 반응하는 방식을 정의합니다. MVC 이전에는 사용자 인터페이스 디자인에서 이러한 개체를 함께 묶는 경향이있었습니다. MVC는 이들을 분리하여 유연성과 재사용 성을 높입니다.
MVC는 뷰와 모델간에 구독 / 알림 프로토콜을 설정하여 뷰와 모델을 분리합니다. 뷰는 해당 모양이 모델의 상태를 반영하는지 확인해야합니다. 모델의 데이터가 변경 될 때마다 모델은 모델에 의존하는 뷰에 알립니다. 이에 대한 응답으로 각 뷰는 자체적으로 업데이트 할 기회를 얻습니다. 이 방법을 사용하면 여러 뷰를 모델에 연결하여 다른 프리젠 테이션을 제공 할 수 있습니다. 모델을 다시 쓰지 않고 새 뷰를 작성할 수도 있습니다.
다음 다이어그램은 모델과 세 가지보기를 보여줍니다. 모델에는 일부 데이터 값이 포함되어 있으며 스프레드 시트, 히스토그램 및 원형 차트를 정의하는보기에는 이러한 데이터가 다양한 방식으로 표시됩니다. 모델은 값이 변경 될 때 해당 뷰와 통신하고 뷰는 모델과 통신하여 이러한 값에 액세스합니다.
액면가에서 취한이 예는 모델에서 뷰를 분리하는 설계를 반영합니다. 그러나 디자인은보다 일반적인 문제에 적용 할 수 있습니다. 즉, 객체를 분리하면 변경 한 객체가 다른 객체의 세부 사항을 알 필요없이 하나의 변경 사항이 다른 많은 사람에게 영향을 줄 수 있습니다. 이보다 일반적인 디자인은 관찰자 (293 페이지) 디자인 패턴으로 설명됩니다.
MVC의 또 다른 기능은 뷰를 중첩 할 수 있다는 것입니다. 예를 들어, 단추의 제어판은 중첩 된 단추보기를 포함하는 복잡한보기로 구현 될 수 있습니다. 객체 관리자의 사용자 인터페이스는 디버거에서 재사용 될 수있는 중첩 된 뷰로 구성 될 수 있습니다. MVC는 View의 하위 클래스 인 CompositeView 클래스를 사용하여 중첩 된 뷰를 지원합니다. CompositeView 객체는 View 객체와 동일하게 작동합니다. 복합 뷰는 뷰를 사용할 수있는 곳이라면 어디에서나 사용할 수 있지만 중첩 뷰도 포함하고 관리합니다.
다시, 우리는이를 구성 요소 중 하나를 취급하는 것처럼 복합 뷰를 처리 할 수있는 디자인으로 생각할 수 있습니다. 그러나 디자인은 객체를 그룹화하고 그룹을 개별 객체처럼 취급하려고 할 때마다 발생하는보다 일반적인 문제에 적용됩니다. 이보다 일반적인 디자인은 합성 (163) 디자인 패턴으로 설명됩니다. 일부 서브 클래스가 기본 객체 (예 : Button)를 정의하고 다른 클래스가 기본 객체를보다 복잡한 객체로 어셈블하는 복합 객체 (CompositeView)를 정의하는 클래스 계층 구조를 작성할 수 있습니다.
MVC를 사용하면 시각적 프레젠테이션을 변경하지 않고도 뷰가 사용자 입력에 응답하는 방식을 변경할 수 있습니다. 예를 들어 키보드에 반응하는 방식을 변경하거나 명령 키 대신 팝업 메뉴를 사용하도록 할 수 있습니다. MVC는 응답 메커니즘을 Controller 객체에 캡슐화합니다. 컨트롤러의 클래스 계층이 있으므로 기존 컨트롤러의 변형으로 새 컨트롤러를 쉽게 만들 수 있습니다.
뷰는 Controller 서브 클래스의 인스턴스를 사용하여 특정 응답 전략을 구현합니다. 다른 전략을 구현하려면 인스턴스를 다른 종류의 컨트롤러로 바꾸십시오. 런타임에 뷰의 컨트롤러를 변경하여 뷰가 사용자 입력에 응답하는 방식을 변경하도록 할 수도 있습니다. 예를 들어, 입력 이벤트를 무시하는 컨트롤러에 단순히 입력을 허용하지 않도록보기를 비활성화 할 수 있습니다.
뷰-컨트롤러 관계는 전략 (315) 디자인 패턴의 예입니다. 전략은 알고리즘을 나타내는 객체입니다. 알고리즘을 정적으로 또는 동적으로 바꾸거나 알고리즘의 변형이 많거나 알고리즘에 캡슐화하려는 복잡한 데이터 구조가있는 경우 유용합니다.
MVC는 팩토리 메소드 (107)와 같은 다른 디자인 패턴을 사용하여 뷰의 기본 컨트롤러 클래스를 지정하고 데코레이터 (175)는 뷰에 스크롤을 추가합니다. 그러나 MVC의 주요 관계는 Observer, Composite 및 Strategy 디자인 패턴으로 제공됩니다.