MVC 아키텍처에서 모델과 뷰는 컨트롤러와 얼마나 밀접하게 연결되어 있습니까?


16

MVC를 사용하는 앱이 있지만 컨트롤러를 설계하는 방법에 대해 조금 어려움을 겪고 있습니다. 예를 들어,보기는 모델 데이터의 일부 하위 집합을 한 번에보고 있습니다. 그러나 이것이 어떻게 배열되어야하는지 확실하지 않습니다. 예를 들어 View 또는 Model이 컨트롤러의 함수를 직접 호출하는 것이 정상입니까? 어떤 종류의 인터페이스를 통해? 아니면 완전히 캡슐화되어 있고 컨트롤러 또는 서로에 대해 알지 못합니까?

편집처럼; 이것은 웹 프레임 워크로 작성되지 않은 사용자 지정 응용 프로그램이므로 여기에서 프레임 워크 관련 세부 정보를 찾고 있지 않으며 자유롭게 선택할 수 있습니다.


1
MVC 아키텍처에서는 경험이 제한되어 있기 때문에 대답하지는 않지만 다른 사람들과 이야기하고 이야기 한 모든 M & V는 서로 밀접하게 연결되어 있지만 C는 아닙니다. M은 일반적으로 C 및 C에서 함수를 호출합니다. V M. 일부 부분 집합에 종종 databinds
스티븐 에버스

8
@ SnOrfus : 그것은 내가 생각했던 것과 정확히 반대입니다 .M & V는 C와 연결되어 있지만 서로 연결되어 있지 않습니다.
DeadMG

1
어떻게 그렇게 많은 답변이 그렇게 잘못 될 수 있습니까? 여기 MS 버전 msdn.microsoft.com/en-us/library/ff649643.aspx를
Reactgular

답변:


15

컨트롤러는 활동 흐름을 제어합니다. 사용자는이 작업을 수행하고 컨트롤러는보기 데이터를 도메인에 전달하여 필요한 모든 작업을 수행합니다. 응답에 따라 컨트롤러는 프레임 워크에 다음보기를 표시 할 프레임 워크에 알려줍니다. 그래서).

따라서 컨트롤러는 어느 정도 도메인 모델에 연결되어야합니다. 즉. 엄격한 정의에 의해 도메인 사이에 서비스 계층을 배치 할 수 있습니다.

또한 뷰 데이터에는 연결되지만 뷰 자체에는 연결되지 않습니다. 즉. "고객 세부 정보를 사용하여 고객보기를 표시합니다."라고 말합니다. 그런 다음 프레임 워크는 해당 뷰를 찾을 위치를 결정합니다.

이제 동일한 데이터의 뷰 모델을 사용하여 뷰에서 도메인 모델을 분리 할 수 ​​있습니다. 일부 개발자는이 작업을 수행하지만 일부는 그렇지 않으며 개인 취향의 문제라고 생각합니다.

Rails에서는 도메인 객체 (ActiveRecord)를 뷰로 푸시하고 뷰가 해당 액세스를 이용하지 않는다는 것을 신뢰합니다 (예 : 뷰에서 customer.save를 호출해서는 안 됨) 사용할 수 있습니다).

.NET 세계에서 우리는 발생해서는 안되는 일을 허용하지 않아 위험을 줄이는 경향이 있으며, 그런 이유로 분리 된 뷰 모델이 더 인기가있는 것 같습니다.


1
뷰 모델은 단위 테스트와 관련하여 매우 일반적인 관행입니다. 일반적으로 도메인 모델 또는 DTO 개체를 뷰 모델에 자동 매핑합니다. 그런 다음 뷰에서 뷰 모델을 사용합니다. 뷰 모델은 쉽게 테스트 할 수 있으며 아래 레이어에 묶이지 않습니다.
CodeART

7

참고 : Robert C. Martin (일명 Bob Uncle Bob)은 그의 기조 연설 인 Architecture the Lost Years 에서이를 훨씬 더 유머러스하게 설명합니다 . 조금 길지만 좋은 개념을 많이 가르칩니다.

tl; dr : MVC와 관련하여 앱을 생각하고 계획하지 마십시오. MVC 프레임 워크는 구현 세부 사항 일뿐입니다.

MVC의 가장 혼란스러운 점은 개발자가 서로 붙어있는 모든 구성 요소를 사용하려고한다는 것입니다.

프레임 워크의 관점이 아닌 프로그램의 관점에서 생각하십시오.

당신의 프로그램은 목적이 있습니다. 데이터를 가져 와서 데이터를 처리하고 일부 데이터를 반환합니다.

그렇게하면 controller프로그램의 전달 메커니즘이됩니다.

  1. 사용자가 프로그램에 요청을 보냅니다 (예 : 장바구니에 제품 추가).
  2. 컨트롤러는 해당 요청 (제품 정보 및 사용자 정보)을 가져오고이 요청을 처리 할 프로그램의 필요한 부분을 호출합니다. $user->addToCart($product)
  3. 프로그램 ( 이 경우 객체의 addToCart기능 user)은 의도 한 작업을 수행하고 응답을 반환합니다 (말하자success ).
  4. 컨트롤러는 다음을 사용하여 응답을 준비합니다 view. 컨트롤러 객체에서$this->render($cartView('success')

이런 방식으로 컨트롤러는 프로그램에서 분리되어 전달 메커니즘으로 사용됩니다. 그들은 당신의 프로그램이 어떻게 작동하는지 알지 못하며, 요청을 위해 프로그램의 어느 부분이 호출되어야 하는지를 알고 있습니다.

다른 프레임 워크를 사용하려면 앱을 변경할 필요가 없으며 요청을 위해 프로그램을 호출하기 위해 관련 컨트롤러를 작성하기 만하면됩니다.

또는 데스크톱 버전을 만들려면 앱이 동일하게 유지되므로 전달 메커니즘을 준비하면됩니다.

그리고 Model . 이를 지속성 메커니즘으로 생각하십시오.

OO 방식으로 프로그램에 데이터를 보유하는 객체가 있습니다.

class User {
    //...
    private $id;
    private $shoppingCart;
    //...
}

class Product {
    //...
    private $id;
    //...
}

장바구니에 제품을 추가하면 제품을 장바구니에 추가 할 수 있습니다 product::id.user::shoppingCart .

데이터를 유지하려는 경우 model 일반적으로 ORM을 사용하여 구성되는 프레임 워크 일부를 사용하여 클래스를 데이터베이스 테이블에 맵핑 할 수 있습니다.

사용하는 ORM을 변경하려는 경우 프로그램은 그대로 유지되며 맵핑 정보 만 변경됩니다. 또는 데이터베이스를 함께 사용하지 않으려면 데이터를 일반 텍스트 파일에 쓰면 앱이 그대로 유지됩니다.


먼저 프로그램을 작성하십시오. 'OO'방식으로 프로그래밍하는 경우 언어의 일반 오래된 개체를 사용하십시오. 처음에는 MVC 측면에서 생각하지 마십시오.


멋진 동영상. 감사. 나는 당신의 해석에 동의하지 않을 것입니다. MVC는 Bob 아저씨가 가진 의미의 세부 사항이 아닙니다. MVC는 자신이 설정 한 "Interactor / Entity / Boundary"패턴과 매우 유사한 아키텍처 패턴입니다. 반면 Spring과 같은 특정 MVC 시스템은 실제로 그가 권장하는 것입니다. 그가 설명 하듯이, "MVC"라고 불리는 이러한 프레임 워크는 일종의 용어입니다.
Edward Strange

예, 사람들이 생각하는 방식으로 썼습니다 MVC. 내가 쓴 이유 MVC Framework입니다.
Hakan Deryal

2

Martin Fowler는 MVC 패러다임을 잘 설명합니다. 여기에 그의 기사에 대한 링크가 있습니다 http://martinfowler.com/eaaDev/uiArchs.html

"분리 된 프리젠 테이션의 아이디어는 실제 세계에 대한 인식을 모델링하는 도메인 객체와 화면에 표시되는 GUI 요소 인 프리젠 테이션 객체를 명확하게 구분하는 것입니다."


1

다음은 일반적인 Java Swing 애플리케이션에서 MVC를 사용하는 방법에 대한 간단한 예입니다.

Button과 TextField를 포함하는 Panel이 있다고 가정 해 봅시다. 버튼을 누르면 이벤트가 발생하여 응용 프로그램에서 일부 상태가 변경됩니다. 상태 변경이 등록되면 TextField가 비활성화됩니다.

그렇다면 이것은 간단한 MVC 응용 프로그램이 취하는 일반적인 접근 방식입니다 ...

컨트롤러는 자체적으로 View 이벤트의 리스너로 등록됩니다. 버튼을 클릭하면보기 자체가 이벤트를 처리하지 않습니다. 컨트롤러는 않습니다. 컨트롤러는 스윙 관련 이벤트를 처리해야하므로 스윙 전용입니다.

컨트롤러는이 알림을 수신하고 누가이를 처리해야하는지 결정해야합니다 (뷰 또는 모델). 이 이벤트는 응용 프로그램의 상태를 변경하므로 데이터 및 프로그램 논리를 담당하는 모델에게 정보를 전달하기로 결정합니다. 일부는 컨트롤러에 프로그램 로직을 배치하는 실수를 저 지르지 만 OOP에서는 모델이 데이터와 동작을 모두 나타냅니다. 그의 마틴 파울러를 읽으십시오.

메시지는 적절한 컨텍스트에서 모델에 의해 수신됩니다. 즉, Swing 또는 기타 GUI 특정 참조에 대한 참조가 완전히 없습니다. 이 메시지는 모델과 모델에만 해당됩니다. Model에서 javax.swing 문을 가져 오면 Model을 올바르게 코딩하지 않은 것입니다.

그런 다음 모델은 상태를 '비활성화 됨'으로 설정하고 관심있는 당사자에게이 모델 변경 사항을 알립니다. 이 이벤트에 관심이있는 뷰는 이미 모델 변경 사항을 관찰자로 등록했습니다. View가 모델 상태 변경 이벤트를 선택하면 TextField를 비활성화합니다. 또한 View가 Controller를 거치지 않고 모델에서 직접 읽기 전용 정보를 얻는 것이 합법적입니다 (보통 이러한 활동에 대해 모델에서 노출 된 특정 인터페이스를 통해).

Presentation과 Business Logic 및 Data Layer 사이의 느슨한 결합을 촉진함으로써 코드의 유지 관리가 훨씬 쉬워집니다. 시스템이 성장함에 따라 MVC에 대한 접근 방식도 커집니다. 예를 들어, 계층 적 MVC는 MVC 트라이어드를 서로 연결하여 하위 시스템을 연결하지 않고 대기업 시스템을 형성하는 데 자주 사용되는 확장입니다.


0

커플 링 (피할 수있는 정렬)에는 상호 관련이 있습니다. 두 클래스 간의 종속성이 . 즉, Foo는 Bar에 의존하고 Bar는 Foo에 의존하므로 다른 하나를 수정하지 않고는 실제로 하나를 수정할 수 없습니다. 나쁜 일이야

그러나 SOME 의존성을 피할 수는 없습니다. 수업은 서로에 대해 조금 알아야합니다. 그렇지 않으면 의사 소통을하지 않습니다.

MVC 패턴에서 컨트롤러는 도메인 모델과 프레젠테이션보기 간의 통신을 제어합니다. 따라서 컨트롤러는 모델에 대해 알고 있어야 할 일을하도록 모델에 대해 충분히 알고 있어야합니다. Controller는 또한 View를 클라이언트 또는 사용자에게 제공 할 수있는 충분한 정보를 알고 있어야합니다. 따라서 모델 컨트롤러는 둘 다에 종속됩니다. 그러나 View는 Controller없이 완벽하게 존재할 수 있습니다. 거기에는 종속성이 없습니다. 마찬가지로 모델에는 컨트롤러에 결함이 없으며 단순히 그 자체입니다. 마지막으로 Model과 View는 서로 완전히 분리되어 있습니다.

기본적으로 컨트롤러는 뷰를 모델에서 분리하여 서로를 알 필요가없는 간접적 인 수준입니다.


아 .. 그 이유는 다운 보트입니다. 컨트롤러가 두 가지 모두에 의존한다는 것을 의미했습니다. 도!
Matthew Flynn

-5

내 경험에 의하면, 일반적으로 모델은에 따라 는 전혀 그러한 결합이있는 경우 ... 종종 관찰자로,보기가 아닌 특정 하나.

보기는 일반적으로보고있는 모든 것에 연결됩니다. 보는 것과 분리 될 수있는 뷰를 만들어 내기는 어렵지만 때로는 부분적인 커플 링 또는 무언가를 가질 수 있습니다.

컨트롤러는 종종 두 가지 모두에 연결되는 경향이 있습니다. 뷰 이벤트를 모델 변경으로 전환하는 것이 중요하기 때문에 이것은 또한 의미가 있습니다.

물론 이것은 내가 관찰 한 경향 일 뿐이며 특정 예에 대해서는 아무 말도하지 않습니다.

MVC가 무엇인지, 그리고 커플 링 관계가 어떤 경향이 있는지 이해하려면 MVC가 어떻게 생겼는지 조사해야합니다. MVC가 작성된 환경은 대화 상자를 작성할 수있는 양식 요소로서 "위젯"이 존재하지 않는 환경이었습니다. "보기"는 상자 였고 물건을 그렸습니다. 텍스트보기는 텍스트를 그리는 상자입니다. 목록보기는 목록을 그리는 상자였습니다. "컨트롤러"는 해당보기에서 발생한 UI 시스템으로부터 모든 마우스 및 키보드 이벤트를 수신했습니다. "textChanged"또는 "selectionChanged"이벤트가 없습니다. 컨트롤러는 이러한 모든 하위 수준 이벤트를 가져와 모델과의 상호 작용을 생성합니다. 모델은 변경 될 때 해당 견해를 알립니다. 우리는이 관계를 "관찰자"로 보게되었습니다.

이것이 MVC 패턴의 본질입니다. 이런 종류의 저수준 UI 프로그래밍은 더 이상 일반적으로 수행되지 않기 때문에 MVC는 여러 방향으로 진화했습니다. 오늘날 그 이름으로가는 것들은 MVC와 거의 같지 않으며 실제로 다른 것으로 불려야합니다. 대화 상자의 의미에서 더 큰 객체와의 전체 상호 작용으로 여전히 사용할 수 있습니다. 그래도 더 좋은 대안이 많이 있습니다.

기본적으로 MVC가 해결하려는 모든 것은 이제 위젯 내부에서 발생하며 더 이상 사용할 필요가 없습니다.


그들이 더 잘 알고 있다고 생각하는 사람들을 위해 :

http://www.codeproject.com/Articles/42830/Model-View-Controller-Model-View-Presenter-and-Mod

http://msdn.microsoft.com/en-us/library/ff649643.aspx

나는 더 많은 것이 확실하지만 그것들은 구글 목록의 최상위에 불과합니다. 보시다시피, 모델은 많은 구현에서 뷰 인터페이스에 크게 의존합니다. 일반적으로 모델을 관찰 할 수 있으며 뷰는 관찰자입니다.

그러나 왜 사실을 알게 되었습니까?

이미 다른 답변에 게시 된 기사는 내 진술을 뒷받침합니다.

http://martinfowler.com/eaaDev/uiArchs.html

사람들이 디자인 산업의 모든 사람들이 잘못했다고 계속 말하고 싶다면 괜찮습니다.


4
이것은 분명히 잘못입니다. 모델은 뷰에 의존해서는 안됩니다! 그 견해가 추상적이거나 인터페이스 인 경우에도 마찬가지입니다. 모델은 프레젠테이션에서 완전히 분리되어야합니다!
팔콘

3
대답이 잘못되었습니다. 모델은 뷰 또는 컨트롤러에 의존하지 않습니다.
CodeART

2
@Crazy Eddie 당신은 말했다 : "일반적으로, 모델은 일반적으로 관찰자로서 특정 뷰가 아닌 뷰에만 의존합니다." 인용 된 기사를 읽었습니까? 그렇게 보이지 않습니다.
CodeART

2
@Crazy Eddie : 나는 엉터리 코드 프로젝트의 누군가가 쓴 것을 상관하지 않습니다. 이것은 끔찍한 디자인입니다. 관찰자를 사용하여 변경 사항을 수신하는 것은 좋지만 프레젠테이션 인터페이스를 도메인 모델에 배치하는 것은 너무 잘못되었습니다. 이 기사에서 인용 된 코드는 MVC와 관련하여 몇 가지 근본적인 방식으로 결함이 있습니다. 심지어 모델이 내재적으로 컨트롤러에 의존하게합니다. 쓰레기 야
팔콘

3
@Crazy Eddie : lol @ downvote 날 뛰기. 내가 당신을 화나게 했습니까?
팔콘

-7
  • 컨트롤러는 모델을 뷰로 디스패치하고 뷰에서 제출 된 모델을 처리하지만 뷰 또는 모델과 밀접하게 연결되지는 않습니다.

컨트롤러가 뷰에 밀접하게 연결되어 있다면 웹 양식의 세계에있을 것입니다. 템플릿 파일에 연결된 코드가 있습니다 (ASP.NET 웹 양식에 적용 가능)

이 때문에 컨트롤러는 모델이나 뷰에 연결되지 않습니다. 요청을 처리하고 응답을 보내는 메커니즘 일뿐입니다.

  • 뷰는 모델과 밀접하게 연결되어 있습니다. 모델을 변경하고 (예 : 속성 변경) 뷰를 변경해야합니다.

  • 모델이 뷰에 단단히 연결되지 않았습니다. 뷰를 변경하면 모델에 영향을 미치지 않습니다.

  • 모델은 컨트롤러 또는 사용되는 뷰에 대해 아무것도 모릅니다. 따라서 모델은 뷰 또는 컨트롤러에 단단히 연결되지 않습니다.

이것을 생각하는 또 다른 방법 :

  • 컨트롤러를 변경합니다.보기 및 모델은 영향을받지 않습니다.

  • 모델을 변경합니다. 모델에 의존하여보기가 중단됩니다.

  • 뷰를 변경합니다. 모델 및 컨트롤러는 영향을받지 않습니다.

MVC 프로젝트에서이 느슨한 결합은 단위 테스트를 쉽게 만듭니다.


1
이건 너무 재밌어 재미 없어 설명 할 가치조차 없습니다. 이 답변을 완전히 무시하십시오.
Reactgular

1
@MathewFoscarini 울음을 멈추고 "정답"을 남겨
주세요

2
lol, MVC의 기본 디자인 이론은 서로 의존하지 않는다는 것입니다.
Reactgular

나는 희망이 의미 만들거야, 당신에 대한 더 많은 정보를 떠 났어요
CodeART
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.