[java] “MVC”의 “컨트롤러”는 무엇입니까?

MVC의 기본 개념을 이해한다고 생각합니다. 모델에는 응용 프로그램의 데이터와 동작이 포함되어 있으며보기는 사용자에게 표시하고 컨트롤러는 사용자 입력을 처리합니다. 내가 불확실 해요 것은 정확히 무엇인지 컨트롤러에 간다.

예를 들어 상당히 간단한 응용 프로그램이 있다고 가정 해 보겠습니다 (특히 Java를 생각하고 있지만 다른 원칙과 동일한 원칙이 적용된다고 가정합니다). 코드를 app.model, app.view및 이라는 3 개의 패키지로 구성 app.controller합니다.

app.model패키지, 나는 응용 프로그램의 실제 행동을 반영하는 몇 가지 클래스가 있습니다. 이들을 extends Observable사용 setChanged()하고 notifyObservers()적절한 경우보기를 업데이트하여보기를 트리거합니다.

app.view패키지는 사용하는 클래스 (또는 디스플레이의 다른 유형에 대한 여러 클래스)가 javax.swing디스플레이를 처리하기 위해 구성 요소를. 이러한 구성 요소 중 일부는 모델로 피드백해야합니다. 올바르게 이해하면 View는 피드백과 관련이 없어야합니다. 피드백은 컨트롤러가 처리해야합니다.

그렇다면 실제로 컨트롤러에 무엇을 넣습니까? public void actionPerformed(ActionEvent e)컨트롤러의 메소드를 호출하여 View에 뷰를 넣 습니까? 그렇다면 컨트롤러에서 유효성 검사 등을 수행해야합니까? 그렇다면 오류 메시지를 다시보기로 피드백하는 방법-모델을 다시 통과해야합니까, 아니면 컨트롤러가 다시보기로 다시 보내야합니까?

확인이 View에서 수행되면 Controller에 무엇을 넣습니까?

긴 질문에 대해 유감스럽게 생각합니다. 프로세스에 대한 이해를 문서화하고 싶었고 누군가 가이 문제를 분명히 밝힐 수 있기를 바랍니다.



답변

당신이 제안한 예에서, 당신은 맞습니다 : 인터페이스에서 “사용자가 ‘이 항목 삭제’버튼을 클릭했습니다”는 기본적으로 컨트롤러의 “삭제”기능을 호출해야합니다. 그러나 컨트롤러는보기의 모양을 모릅니다. 따라서 “어떤 항목을 클릭 했습니까?”와 같은 정보를 수집해야합니다.

대화 형태로 :

보기 : “이봐, 컨트롤러, 사용자가 방금 항목 4를 삭제하고 싶다고 말 했어요.”
컨트롤러 : “음, 자신의 자격 증명을 확인한 후, 그는 그렇게 할 수 있습니다 … 이봐, 모델, 나는 당신이 항목 4를 얻고 그것을 삭제하기 위해 무엇이든하길 원합니다.”
모델 : “항목 4 … 가져 왔습니다. 삭제되었습니다. 컨트롤러로 돌아갑니다.”
Controller : “여기, 새로운 데이터 세트를 수집하겠습니다.
보기 : “멋지네요, 이제 새 세트를 사용자에게 보여 드리겠습니다.”

이 섹션의 끝에는 옵션이 있습니다.보기에서 별도의 요청을 수행하여 “가장 최근 데이터 세트를 제공”하여 더 순수하거나 컨트롤러가 “삭제를 사용하여 새 데이터 세트를 암시 적으로 반환합니다. “작업.


답변

문제 MVC는 사람들이 뷰, 컨트롤러 및 모델이 가능한 한 독립적이어야한다고 생각한다는 것입니다. 그것들은 뷰가 아니며 컨트롤러가 종종 얽혀 있다고 생각합니다 M(VC).

컨트롤러는 사용자 인터페이스의 입력 메커니즘으로, 특히 GUI와 함께보기에서 종종 엉켜 있습니다. 그럼에도 불구하고 뷰가 출력되고 컨트롤러가 입력됩니다. 뷰는 종종 해당 컨트롤러없이 작동 할 수 있지만 일반적으로 뷰가 없으면 컨트롤러의 유용성이 훨씬 떨어집니다. 사용자 친화적 인 컨트롤러는 뷰를 사용하여보다 의미 있고 직관적 인 방식으로 사용자 입력을 해석합니다. 이것이 컨트롤러 개념을보기에서 분리하기 어렵게 만드는 것입니다.

밀폐 된 상자의 감지 영역에서 무선 제어 로봇을 모델로 생각하십시오.

모델은 출력 (디스플레이) 개념이없는 상태 및 상태 전이에 관한 것입니다. 현장에서 로봇의 위치를 ​​파악할 수 있고 로봇은 위치를 전환하는 방법을 알고 있습니다 (앞으로 / 뒤로 / 왼쪽 / 오른쪽으로 이동합니다.보기 나 컨트롤러없이 쉽게 구상 할 수 있지만 유용한 것은 없습니다.

컨트롤러가없는보기, 예를 들어 스크롤 콘솔 아래로 스트리밍하는 (x, y) 좌표로 로봇 위치를보고있는 다른 방에있는 네트워크의 다른 방에있는 누군가를 생각하십시오. 이 뷰는 모델의 상태 만 표시하지만이 녀석에는 컨트롤러가 없습니다. 컨트롤러없이이보기를 쉽게 구상 할 수 있습니다.

예를 들어 무선 주파수 컨트롤러가 로봇의 주파수에 맞춰진 벽장에 잠겨있는 사람이 보이지 않는 컨트롤러를 생각해보십시오. 이 컨트롤러는 입력을 보내고 있으며 모델에 수행중인 작업을 모를 경우 상태 전환을 유발합니다 (있는 경우). 구상하기는 쉽지만보기에서 일종의 피드백 없이는 실제로 유용하지 않습니다.

가장 사용자 친화적 인 UI는 컨트롤러와 뷰를 조정하여보다 직관적 인 사용자 인터페이스를 제공합니다. 예를 들어 로봇의 현재 위치를 2D로 표시하는 터치 스크린이있는 뷰 / 컨트롤러가 사용자가 로봇의 바로 앞에있는 지점을 터치 할 수 있다고 상상해보십시오. 컨트롤러는 뷰포트의 위치 및 스케일, 화면상의 로봇의 픽셀 위치에 대해 터치 된 스팟의 픽셀 위치 등 뷰에 대한 세부 정보가 필요합니다. 라디오 컨트롤러).

아직 질문에 대답 했습니까? 🙂

컨트롤러는 모델이 상태를 전환하는 데 사용되는 사용자의 입력을받는 것입니다. 뷰와 컨트롤러를 분리 된 상태로 유지하려고하지만 서로 상호 의존적 인 경우가 많으므로 경계가 모호한 경우 괜찮습니다. 예를 들어 별도의 패키지로 뷰와 컨트롤러를 깔끔하게 분리하지 못할 수 있습니다. 좋아하지만 괜찮습니다. 뷰가 모델과 다르기 때문에 컨트롤러가 뷰와 완전히 분리되지 않을 수도 있습니다.

… 컨트롤러에서 유효성 검사 등을 수행해야합니까? 그렇다면 오류 메시지를 다시보기로 피드백하는 방법-모델을 다시 통과해야합니까, 아니면 컨트롤러가 다시보기로 다시 보내야합니까?

확인이 View에서 수행되면 Controller에 무엇을 넣습니까?

링크 된 뷰와 컨트롤러는 모델을 거치지 않고 자유롭게 상호 작용해야한다고 말합니다. 컨트롤러는 사용자의 입력을 받아 유효성 검사를 수행해야하지만 (아마도 모델 및 / 또는보기의 정보를 사용하여) 유효성 검사에 실패하면 컨트롤러가 관련보기를 직접 업데이트 할 수 있어야합니다 (예 : 오류 메시지).

이것에 대한 산성 테스트는 독립적 인 견해 (예 : 네트워크를 통해 로봇 위치를보고있는 다른 방의 사람)가 다른 사람의 유효성 검사 오류 (예 : 옷장에있는 사람)의 결과로 볼 수 있는지 여부입니다 로봇에게 현장에서 물러나라고 지시했습니다. 일반적으로 대답은 아니오입니다. 유효성 검사 오류로 인해 상태 전이가 방지되었습니다. 상태 추적이없는 경우 (로봇이 이동하지 않은 경우) 다른 견해를 말할 필요가 없습니다. 옷장에있는 사람은 단지 잘못된 전환 (보기가 안 됨-잘못된 사용자 인터페이스)을 유발하려고 시도한 피드백을 얻지 못했으며 아무도 그 사실을 알 필요가 없습니다.

터치 스크린을 가진 사람이 로봇을 현장 밖으로 보내려고한다면, 로봇을 감지 구역 밖으로 보내 로봇을 죽이지 말라고하는 사용자에게 친근한 메시지를 받았지만, 아무도 이것을 알 필요가 없습니다.

다른 뷰 이러한 오류에 대해 알아야 할 경우 사용자의 입력과 결과 오류가 모델의 일부이며 전체가 조금 더 복잡 하다는 것을 효과적으로 말하고 있습니다 …


답변

다음은 MVC의 기본 사항에 대한 좋은 기사 입니다.

그것은 …

컨트롤러-컨트롤러는 뷰와의 상호 작용을 모델에서 수행 할 동작으로 변환합니다.

다시 말해 비즈니스 로직입니다. 컨트롤러는보기에서 사용자가 수행 한 작업에 응답하고 응답합니다. 유효성 검사를 여기에두고 유효성 검사에 실패하거나 성공하면 적절한보기를 선택합니다 (오류 페이지, 메시지 상자 등).

Fowler 에는 또 다른 좋은 기사가 있습니다.


답변

MVC 패턴은 단순히 프레젠테이션 (=보기) 과 비즈니스 로직 (= 모델) 을 분리 하기를 원합니다 . 컨트롤러 부분은 혼동을 일으킬 수 있습니다.


답변

실제로 컨트롤러 개념이 특히 유용한 개념을 찾지 못했습니다. 코드에서 엄격한 모델 / 뷰 분리를 사용하지만 명확하게 정의 된 컨트롤러는 없습니다. 불필요한 추상화 인 것 같습니다.

개인적으로 본격적인 MVC는 혼란스럽고 지나치게 복잡한 디자인으로 쉽게 이어진다는 점에서 팩토리 디자인 패턴처럼 보입니다. 건축 우주 비행사가 되지 마십시오 .


답변

귀하의 질문에 근거하여 모델의 역할에 약간 헷갈리는 느낌이 들었습니다. 모델은 응용 프로그램과 관련된 데이터에 고정됩니다. 앱에 데이터베이스가있는 경우 모델의 작업은 데이터베이스와 대화하는 것입니다. 또한 해당 데이터와 관련된 간단한 논리도 처리합니다. TABLE.foo == “Hooray!”인 모든 경우에 대해 말하는 규칙이있는 경우 그리고 TABLE.bar == “휴가!” 그런 다음 TABLE.field = “W00t!”를 설정하면 모델에서 처리하게됩니다.

컨트롤러는 대부분의 응용 프로그램 동작을 처리해야합니다. 따라서 귀하의 질문에 대답하십시오 :

Controller의 메소드를 호출하여 공용 void actionPerformed (ActionEvent e)를 View에 넣습니까?

나는 아니오라고 말할 것입니다. 나는 그것이 컨트롤러에 살아야한다고 말하고 싶습니다. View는 단순히 사용자 인터페이스에서 오는 데이터를 Controller에 공급하고 Controller가 응답 할 호출 할 메소드를 결정하게합니다.

그렇다면 컨트롤러에서 유효성 검사 등을 수행해야합니까?

검증의 대부분은 실제로 Controller에 의해 수행되어야합니다. 데이터가 유효한지 여부에 대한 질문에 답해야하며, 유효하지 않은 경우 적절한 오류 메시지를 View에 제공하십시오. 실제로, 사용자 환경을 개선하기 위해 간단한 온 전성 검사를보기 계층에 통합 할 수 있습니다. (주로 웹 환경을 생각하고 있습니다. 사용자가 전체 제출-> 프로세스->로드 페이지주기를 기다리지 않고 사용자가 “제출”을 누르는 순간 오류 메시지가 표시되도록 할 수 있습니다. .) 조심해; 당신은 필요 이상으로 노력을 복제하고 싶지 않으며 많은 환경에서 (웹을 생각하고 있습니다) 사용자 인터페이스에서 오는 모든 데이터를 불결한 더러운 팩으로 취급 해야하는 경우가 종종 있습니다 당신이 할 때까지 거짓말

그렇다면 오류 메시지를 다시보기로 피드백하는 방법-모델을 다시 통과해야합니까, 아니면 컨트롤러가 다시보기로 다시 보내야합니까?

Controller가 알려줄 때까지 View가 다음에 어떤 일이 발생하는지 알 필요가없는 프로토콜을 설정해야합니다. 사용자가 해당 버튼을 after 후 어떤 화면이 표시됩니까? View는 알 수 없으며 Controller는 방금 얻은 데이터를 볼 때까지 알 수 없습니다. “예상 한대로이 다른 화면으로 이동”또는 “이 화면을 그대로 유지하고이 오류 메시지를 표시하십시오”일 수 있습니다.

내 경험상 모델과 뷰 사이의 직접적인 통신은 매우 제한적이어야하며 뷰는 모델의 데이터를 직접 변경해서는 안됩니다. 컨트롤러의 작업이어야합니다.

확인이 View에서 수행되면 Controller에 무엇을 넣습니까?

위 참조; 실제 검증은 컨트롤러에 있어야합니다. 그리고 지금까지 컨트롤러에 무엇을 넣을 지에 대한 아이디어가 있기를 바랍니다. 🙂

가장자리에서 약간 흐릿해질 수 있습니다. 소프트웨어 엔지니어링만큼 복잡한 모든 것들과 마찬가지로 판결 요청도 풍부 할 것입니다. 최선의 판단을하고이 앱 내에서 일관성을 유지하고 배운 교훈을 다음 프로젝트에 적용하십시오.


답변

컨트롤러는 실제로 View의 일부입니다. 요청을 수행하는 데 필요한 서비스를 파악하고,보기에서 값을 서비스 인터페이스에 필요한 오브젝트로 비 정렬 화하고, 다음보기를 판별하고, 다음보기가 사용할 수있는 양식으로 응답을 마샬링하는 것이 목적입니다. . 또한 발생 된 예외를 처리하고 사용자가 이해할 수있는보기로 렌더링합니다.

서비스 계층은 사용 사례, 작업 단위 및 모델 객체를 알고있는 것입니다. 컨트롤러는보기 유형마다 다릅니다. 데스크톱, 브라우저 기반, Flex 또는 모바일 UI에 동일한 컨트롤러가 없습니다. 저는 이것이 실제로 UI의 일부라고 말합니다.

서비스 지향 : 작업이 완료되는 곳입니다.