나는 과거에 MVP와 MVC를 사용해 왔으며, MVP가 그것이 실행 흐름을 훨씬 더 잘 제어한다는 점에서 MVP를 선호합니다.
인프라 (데이터 저장소 / 리포지토리 클래스)를 만들어 샘플 데이터를 하드 코딩 할 때 문제없이 사용하므로 이제 GUI로 이동하여 MVP를 준비하고 있습니다.
섹션 A
MVP가 뷰를 시작점으로 사용하는 것을 보았습니다. 즉, 뷰 생성자 메소드에서 프리젠터를 작성합니다. 그러면 프리젠터가 모델을 작성하고 필요에 따라 이벤트를 연결합니다.
또한 발표자를 뷰 포인트, 모델, 발표자가 생성되는 진입 점으로 보았습니다.이 발표자는 이벤트를 연결하기 위해 생성자에 뷰 및 모델 객체가 제공됩니다.
2에서와 같이 모델은 발표자에게 전달되지 않습니다. 대신 모델은 메소드가 호출되고 응답이 직접 리턴되는 정적 클래스입니다.
섹션 B
뷰와 모델을 동기화 상태로 유지하는 측면에서 보았습니다.
보기의 값이 변경 될 때마다 (예 :
TextChanged
.Net / C #의 이벤트) 이것은DataChangedEvent
모델에 전달 된를 실행하여 항상 동기화 상태를 유지합니다. 그리고 모델이 변경되는 경우 (예 : 청취하는 백그라운드 이벤트) 뷰를 올리는 것과 동일한 아이디어를 통해 뷰가 업데이트됩니다DataChangedEvent
. 사용자가 변경 사항을 커밋하려고하면 변경 사항이 적용SaveEvent
되어 모델로 전달되어 저장됩니다. 이 경우 모델은 뷰의 데이터를 모방하고 동작을 처리합니다.# b1과 유사하지만 뷰는 항상 모델과 동기화되지 않습니다. 대신 사용자가 변경 사항을 커밋하려고하면
SaveEvent
해고되고 발표자는 최신 세부 정보를 가져 와서 모델에 전달합니다. 이 경우 모델은 뷰 데이터에 대한 조치가 필요할 때까지 뷰 데이터에 대해 알지 못하며,이 경우 필요한 모든 세부 사항이 전달됩니다.
섹션 C
뷰에 비즈니스 오브젝트 표시, 즉 기본 데이터가 아닌 오브젝트 (MyClass) (int, double)
보기에는 도메인 / 비즈니스 오브젝트로 표시 할 모든 데이터에 대한 특성 필드가 있습니다. 보기는 TreeView의 노드로 속성을 처리하더라도 속성 을
view.Animals
노출합니다IEnumerable<IAnimal>
. 그런 다음 선택한 동물의 경우 속성으로 노출SelectedAnimal
됩니다IAnimal
.뷰에는 도메인 객체에 대한 지식이 없으며 기본 / 프레임 워크 (.Net / Java) 포함 객체 유형에 대한 속성 만 노출됩니다. 이 경우 발표자는 어댑터 오브젝트에 도메인 오브젝트를 전달한 다음 지정된 비즈니스 오브젝트를보기에 표시된 제어로 변환합니다. 이 경우 어댑터는 뷰뿐만 아니라 뷰의 실제 컨트롤에도 액세스 할 수 있어야하므로보다 밀접하게 연결됩니다.
섹션 D
단일 컨트롤을 만드는 데 사용되는 다중 뷰 즉, 다른 유형의 객체를 저장하는 것과 같은 간단한 모델로 복잡한 뷰를 가질 수 있습니다. 적절한 컨트롤이 표시된 항목을 클릭 할 때마다 측면에 메뉴 시스템이있을 수 있습니다.
뷰 인터페이스를 통해 노출되는 모든 개별 컨트롤을 포함하는 하나의 거대한 뷰를 만듭니다.
몇 가지 견해가 있습니다. 메뉴에 대한 하나의보기와 빈 패널이 있습니다. 이보기는 필요한 다른보기를 작성하지만 표시하지 않습니다 (visible = false).이보기는 포함 된 각보기 (예 : 하위보기)의 인터페이스도 구현하므로 한 발표자에게 노출 될 수 있습니다. 빈 패널은 다른보기 (
Controls.Add(myview)
) 및 ((myview.visible = true
) 로 채워집니다 . 이러한 "자식"보기에서 발생한 이벤트는 부모보기에 의해 처리되며,이보기는 이벤트를 발표자에게 전달하고, 그 반대로 자식 요소에 이벤트를 다시 공급하기 위해 비자를 전달합니다.각 상위 뷰 또는 작은 하위 뷰는 각각 자체 발표자와 모델에 연결됩니다. 문자 그대로 뷰 컨트롤을 기존 양식에 드롭 할 수 있으며 기능이 준비되어 있으므로 장면 뒤의 발표자에 배선하면됩니다.
섹션 E
위의 예에서 MVP가 수행 된 방식을 기반으로 모든 인터페이스가 제공되는 경우 상호 호환되지 않을 수 있으므로이 답변에 영향을 미칩니다.
모든 것에는 인터페이스,보기, 발표자 및 모델이 있습니다. 그러면 이들 각각은 분명히 구체적인 구현을 갖습니다. 구체적인 견해, 모델 및 발표자가 하나 뿐인 경우에도 마찬가지입니다.
뷰와 모델에는 인터페이스가 있습니다. 뷰와 모델이 다를 수 있습니다. 발표자는 뷰 및 모델 객체를 생성 / 제공하며 객체간에 메시지를 전달하는 역할 만합니다.
뷰에만 인터페이스가 있습니다. 모델에는 정적 메소드가 있으며 작성되지 않으므로 인터페이스가 필요하지 않습니다. 다른 모델을 원하면 발표자는 다른 정적 클래스 메서드 집합을 호출합니다. 정적 인 모델은 발표자와 연결되지 않습니다.
개인적인 생각
내가 제시 한 모든 다른 변형 (대부분 나는 어떤 형태로 사용했을 것입니다)에서 더 많은 것이 있다고 확신합니다. 나는 데이터 복제 및 이벤트 발생을 줄이기 위해 비즈니스 로직을 MVP, B2 외부에서 재사용 할 수 있도록 A3을 선호합니다. 다른 클래스에 추가하지 않는 C1은 소량의 테스트 불가능한 논리를 뷰에 넣었는지 (도메인 객체가 시각화되는 방법) 코드 검토 또는 애플리케이션에서 간단히 볼 수 있습니다. 논리가 복잡한 경우 어댑터 클래스에 동의하지만 모든 경우에 동의하지는 않습니다. 섹션 D의 경우 D1이 메뉴 예에 비해 너무 큰 뷰를 생성한다고 생각합니다. 나는 전에 D2와 D3을 사용했다. D2의 문제는 이벤트를 발표자에서 올바른 자식보기로 라우팅하기 위해 많은 코드를 작성해야하며 드래그 앤 드롭 호환이 불가능하다는 것입니다. 각각의 새로운 제어는 단일 발표자를 지원하기 위해 더 많은 배선이 필요합니다. D3은 내가 선호하는 선택이지만 뷰가 매우 간단하거나 재사용 할 필요가없는 경우에도 뷰를 처리하기 위해 발표자와 모델로 더 많은 클래스를 추가합니다. 나는 상황에 따라 D2와 D3의 혼합이 가장 좋다고 생각합니다. 섹션 E와 관련하여 인터페이스가있는 모든 것이 과도 할 수 있다고 생각합니다. 도메인 / 비즈니스 오브젝트에 대해 이미 수행하고 있으며 "디자인"에서 이점을 얻지 못하는 경우가 많지만 테스트에서 오브젝트를 조롱하는 데 도움이됩니다. 개인적으로 나는 이전에 작업 한 2 개의 프로젝트에서 E3가 사용되는 것을 보았지만 E2를 고전적인 솔루션으로 볼 것입니다. 나는 상황에 따라 D2와 D3의 혼합이 가장 좋다고 생각합니다. 섹션 E와 관련하여 인터페이스가있는 모든 것이 과도 할 수 있다고 생각합니다. 도메인 / 비즈니스 오브젝트에 대해 이미 수행하고 있으며 "디자인"에서 이점을 얻지 못하는 경우가 많지만 테스트에서 오브젝트를 조롱하는 데 도움이됩니다. 개인적으로 나는 이전에 작업 한 2 개의 프로젝트에서 E3가 사용되는 것을 보았지만 E2를 고전적인 솔루션으로 볼 것입니다. 나는 상황에 따라 D2와 D3의 혼합이 가장 좋다고 생각합니다. 섹션 E와 관련하여 인터페이스가있는 모든 것이 과도 할 수 있다고 생각합니다. 도메인 / 비즈니스 오브젝트에 대해 이미 수행하고 있으며 "디자인"에서 이점을 얻지 못하는 경우가 많지만 테스트에서 오브젝트를 조롱하는 데 도움이됩니다. 개인적으로 나는 이전에 작업 한 2 개의 프로젝트에서 E3가 사용되는 것을 보았지만 E2를 고전적인 솔루션으로 볼 것입니다.
질문
MVP를 올바르게 구현하고 있습니까? 그것에 대한 올바른 방법이 있습니까?
나는 변형이있는 Martin Fowler의 작품을 읽었으며 MVC를 처음 시작했을 때를 기억했지만 개념을 이해했지만 처음에는 진입 점이 어디 있는지 알아낼 수 없었습니다. 모든 것이 자체 기능이 있지만 원래는 제어하고 만드는 것 MVC 객체 세트