MVC 패턴을 C # WinForms 애플리케이션에 어떻게 적용 할 수 있습니까?


11

저는 MVC 패턴을 사용하여 GUI를 디자인 한 C ++ 개발자입니다.

최근에 C #으로 돌아가고 싶었고 Windows Forms 응용 프로그램을 설정했지만 이제는 MVC 호환 구조로 푸시하는 방법이 약간 없어졌습니다.

내가 현재하려고하는 것은 WinForms에 대해 주어진 클래스를 뷰로 "선언하고"백그라운드에서 모델 및 컨트롤러에 대한 클래스를 추가하는 것입니다. 그러나 버튼 클릭과 같은 이벤트와 상호 작용하는 방법은 확실하지 않습니다. 일반적으로 이러한 이벤트를 컨트롤러로 리디렉션하고 완료되면 View에서 작업을 수행합니다.

이 별자리에서는 꽤 불만족 스럽습니다. 예를 들어 "종료"버튼을 구현하려면 View에서 Controller로 이벤트를 리디렉션하고 내 View에서 추가 공용 메소드를 구현해야합니다. 첫 번째 인스턴스의 View에서 Close ()를 간단히 호출 할 수 있습니다.

나에게 조언이 있습니까? C #에서 Windows Forms에 대한 이해가 아직 MVC 구현을 시도하기에 충분하지 않습니까? 양식 클래스에 잘못된 역할을합니까? MVC는 단순히이 사용 사례에 부적절한 아키텍처입니까?


1
구약 질문. 그러나 왜 WInforms? WPF는 Winform을 대체하기위한 것이며 MVC (Well Technically MVVM)를 지원합니다. 비록 WPF 학습 곡선이 가파를 수 있다고 말할 것입니다. (하지만
Peter M

1
@PeterM : 10 년이 지난 후에도 WPF는 빨라지고 여전히 느립니다.
whatsisname

3
@whatsisname의 의견을 말하면 WPF는 더 큰 응용 프로그램에 맞춰져 있습니다. Winforms가 더 단순하기 때문에 더 작은 응용 프로그램이 Winforms에 더 잘 제공 될 수 있습니다. 그러나 그 주장을하고 싶다면 Winforms 응용 프로그램이 MVP가 필요 없을 정도로 충분히 작다는 주장을 할 수도 있습니다. MVVM은 WPF에 구워졌습니다. WPF에는 벡터 기반 그래픽이 있으므로 Winforms와 동일한 크기 문제가 발생하지 않습니다. WPF는 구성이 매우 쉽고 (다른 컨트롤에 컨트롤을 쉽게 넣을 수 있음) 킬러 데이터 바인딩이 있습니다. 싫어하는 것은 무엇입니까?
Robert Harvey

3
@whatsisname WPF는 빠를 지 모르지만 장난감 프로그램 이상으로 Winforms보다 훨씬 덜 빠릅니다.
Peter M

2
사내 데스크톱 프로그램의 경우 그렇게 말하고 싶습니다. 그러나 많은 기업들이 단순히 설치가 필요하지 않기 때문에 비즈니스 운영에 브라우저 기반 응용 프로그램을 선호합니다.
Robert Harvey

답변:


3

우연히도, 저는 MVC 이후에 패턴 화 된 WinForms 프로젝트를 진행하고 있습니다. 나는 이것이 완벽한 해답은 아니지만 내 전반적인 디자인을 설명하고 이것이 당신이 당신의 자신을 생각해내는 데 도움이되기를 바랍니다.

이 프로젝트를 시작하기 전에 내가 읽은 내용을 기반으로, 이것을 구현하는 "올바른"방법이없는 것 같습니다. 간단한 OOP 및 MVC 설계 원칙을 따르고 워크 플로를 개발할 때 나머지는 시행 착오였습니다.

MVC는 단순히이 사용 사례에 부적절한 아키텍처입니까?

아니 ..? 귀하의 질문에 그에 대한 직접적인 대답을 제공하기에 충분한 맥락이 없습니다. 우선 MVC를 사용하는 이유는 무엇입니까? 프로젝트의 비 기능적 요구 사항은 무엇입니까? 프로젝트가 매우 무겁습니까? 보안에 더 관심이 있고 계층화 된 아키텍처를 원하십니까? 프로젝트의 주요 구성 요소는 무엇입니까? 각 구성 요소마다 다른 디자인 패턴이 필요할 수 있습니다. 처음에이 디자인 패턴을 사용하려는 이유를 찾고 자신의 질문에 대답 할 수 있습니다.)

MVC를 사용하는 이유 : 제 생각에 이해하기에는 상당히 단순한 디자인 패턴이며 제 디자인은 사용자의 상호 작용에 크게 의존합니다. MVC를 통해 개발자가 우려 사항을 분리 할 수있는 방식은 저의 애플리케이션에도 충분합니다. 이것은 내 코드를 만드는 작정 더 유지 보수 및 검증.

또한 하이브리드 디자인을 더 많이 사용한다고 가정합니다. 일반적으로 소프트웨어 엔지니어링에 제시된 이상적인 개념은 실제로 실제로 적용되지는 않습니다. 프로젝트 요구에 맞게 디자인을 수정할 수 있습니다. 옳고 그른 것에 얽매일 필요가 없습니다. 일반적인 관행이 있지만 발로 쏘지 않는 한 규칙은 항상 구부러 지거나 깨질 수 있습니다.

구현은 고급 구성으로 시작하여 필요한 구성 요소에 대한 아이디어를 얻었습니다. 이 방법으로 시작하여 아키텍처에서 작업하는 것이 가장 좋습니다. 다음은 프로젝트의 패키지 다이어그램입니다 (StarUML에서 생성됨). 여기에 이미지 설명을 입력하십시오

프레젠테이션 계층을 제외한 모든 단일 계층은 메시징 시스템에 따라 다릅니다. 이는 해당 계층의 하위 계층과 하위 시스템이 서로 통신하는 데 사용하는 일반적인 "언어"입니다. 필자의 경우 수행 할 수있는 작업을 기반으로 간단한 열거였습니다. 다음 단계로 넘어갑니다.

작업 또는 명령을 구현의 기초로 생각하십시오. 응용 프로그램에서 무엇을 하시겠습니까? 가장 기본적인 작업으로 분류하십시오. 예를 들면 다음과 같습니다. CreateProject, WriteNotes, SaveProject, LoadProject 등. GUI (또는 폼 클래스)는 버튼 누름과 같은 일부 이벤트가 발생합니다. 모든 작업에는 관련된 컨트롤러 방법이 있습니다. 이 경우 Exit와 같은 것이 너무 간단합니다. 응용 프로그램은 Form 클래스에서 간단히 닫을 수 있습니다. 그러나 먼저 일부 응용 프로그램 데이터를 파일에 유지하려고한다고 가정 해보십시오. 버튼 누름 방식 내 각 컨트롤러 클래스에서 "저장"메소드를 호출합니다.

여기서 컨트롤러는 서비스 클래스에서 올바른 조작 세트를 호출합니다. 내 응용 프로그램의 서비스 클래스는 도메인 계층에 대한 인터페이스 역할을합니다. 컨트롤러 메소드 호출 (GUI)에서 수신 한 입력의 유효성을 검사하고 데이터 모델을 조작합니다.

유효성 검사와 해당 개체 조작이 완료되면 서비스 메서드는 메시지 코드를 컨트롤러에 반환합니다. 예를 들면 다음과 같습니다 MessageCodes.SaveSuccess. 컨트롤러와 서비스 클래스는 모두 도메인 개체 및 / 또는 그룹화 할 수있는 일반적인 작업 집합을 기반으로했습니다.

예 : FileMenuController(작업 : NewProject, SaveProject, LoadProject)-> ProjectServices(CreateProject, PersistProjectToFile, LoadProjectFromFile). Project데이터 모델에서 도메인 클래스는 어디에 있습니까 ? 필자의 경우 컨트롤러 및 서비스 클래스는 정적 메소드가있는 인스턴스화 할 수없는 클래스였습니다.

그런 다음 컨트롤러는 작업이 성공적으로 완료되지 않은 것으로 인식합니다. 이제 컨트롤러에는 프레젠테이션 계층과 상호 작용하는 데 사용되는 자체 메시징 시스템이 있으므로 서비스와 프레젠테이션 계층 간의 이중 종속성이 있습니다. 이 경우 패키지 ViewState에서 호출 된 클래스 ViewModels는 항상 컨트롤러에 의해 GUI로 리턴됩니다. 이 상태에는 다음과 같은 정보가 포함됩니다. " 응용 프로그램을 유효한 상태로 설정하려고 시도한 상태입니까? ", " 수행하려고 시도한 조작에 대한 사람이 읽을 수있는 메시지 및 성공 또는 실패한 이유 (오류 메시지) "및 ViewModel클래스 와 같은 정보가 있습니다.

ViewModel클래스에는 GUI가보기를 업데이트하는 데 사용할 도메인 계층의 관련 데이터가 포함되어 있습니다. 이 뷰 모델은 도메인 클래스처럼 보이지만 제 경우에는 매우 마른 개체를 사용했습니다. 기본적으로 그들은 동작이 거의 없으며 응용 프로그램의 하위 수준 상태에 대한 정보를 릴레이합니다. 즉, 나는 결코 프리젠 테이션 계층에 내 도메인 클래스를 포기하려고하지 않습니다. 이것이 패키지 ControllersServices패키지가 서비스 계층을 두 부분으로 나누는 이유이기도합니다 . 컨트롤러는 도메인 클래스를 처리하거나 상태를 확인하지 않습니다. GUI 관련 데이터를 서비스가 사용할 수있는 도메인 관련 데이터로 또는 그 반대로 변환하는 경계 역할을합니다. 컨트롤러에 서비스 로직을 포함 시키면 매우 뚱뚱 해질 수 있습니다 유지 보수가 어려운 컨트롤러.

이것이 당신에게 출발점을 제공하기를 바랍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.