winform에서 프로젝트를 올바르게 구성하는 방법은 무엇입니까?


26

얼마 전에 나는 winform 응용 프로그램을 만들기 시작했으며 그 당시에는 작았으며 프로젝트를 구성하는 방법에 대해서는 전혀 생각하지 않았습니다.

그 이후로 필요에 따라 추가 기능을 추가하고 프로젝트 폴더가 점점 커지고 있으며 이제 프로젝트를 어떤 식 으로든 구조화해야 할 시점이라고 생각하지만 올바른 방법이 무엇인지 잘 모르겠으므로 질문이 거의 없습니다.

프로젝트 폴더를 올바르게 재구성하는 방법은 무엇입니까?

현재 나는 다음과 같은 것을 생각하고 있습니다.

  • 양식 폴더 만들기
  • 유틸리티 클래스를위한 폴더 생성
  • 데이터 만 포함하는 클래스 폴더 만들기

클래스를 추가 할 때 명명 규칙은 무엇입니까?

클래스 이름 만보고 기능을 식별 할 수 있도록 클래스 이름을 바꿔야합니까? 예를 들어, 모든 양식 클래스의 이름을 바꾸면 이름이 Form으로 끝납니다 . 또는 특별한 폴더가 생성 된 경우 필요하지 않습니까?

수행 할 작업 기본 양식의 모든 코드가 Form1.cs로 끝나는 것은 아닙니다.

내가 직면 한 또 다른 문제는 내가 추가하는 각 기능에 따라 기본 양식이 점점 커짐에 따라 코드 파일 (Form1.cs)이 실제로 커지고 있다는 것입니다. 예를 들어 TabControl이 있고 각 탭에는 많은 컨트롤이 있으며 모든 코드는 Form1.cs에 있습니다. 이것을 피하는 방법?

또한 이러한 문제를 다루는 기사 나 책을 알고 있습니까?

답변:


24

일반적인 함정에 빠진 것처럼 보이지만 걱정하지 마십시오. 고정 될 수 있습니다 :)

먼저 응용 프로그램을 조금 다르게보고 청크로 분할해야합니다. 청크를 두 방향으로 나눌 수 있습니다. 먼저 제어 코드 (비즈니스 규칙, 데이터 액세스 코드, 사용자 권한 코드, 모든 종류의 것들)를 UI 코드와 분리 할 수 ​​있습니다. 두 번째로 UI 코드를 여러 덩어리로 나눌 수 있습니다.

따라서 후자를 먼저 수행하여 UI를 청크로 나눕니다. 가장 쉬운 방법은 UI를 usercontrols로 작성하는 단일 호스트 양식을 갖는 것입니다. 각 사용자 정의 컨트롤은 양식 영역을 담당합니다. 응용 프로그램에 사용자 목록이 있다고 가정하고 사용자를 클릭하면 아래의 텍스트 상자에 세부 정보가 채워집니다. 한 명의 사용자가 사용자 목록의 표시를 관리하고 두 번째 사용자가 사용자의 세부 사항 표시를 관리하도록 할 수 있습니다.

실제 트릭은 컨트롤 간의 통신을 관리하는 방법입니다. 서로 무작위로 참조를 잡고 메소드를 호출하는 양식의 30 개의 사용자 정의 컨트롤을 원하지 않습니다.

따라서 각 컨트롤에 대한 인터페이스를 만듭니다. 인터페이스에는 컨트롤이 수락 할 작업과 발생하는 이벤트가 포함됩니다. 이 앱에 대해 생각할 때 목록 상자 목록 선택이 변경 되어도 상관 없습니다. 새로운 사용자가 변경되었다는 사실에 관심이 있습니다.

따라서 예제 앱을 사용하여 사용자 목록 상자를 호스팅하는 컨트롤의 첫 번째 인터페이스에는 사용자 개체를 전달하는 UserChanged라는 이벤트가 포함됩니다.

목록 상자가 지루하고 3D 줌 매직 매직 컨트롤을 원할 경우 동일한 인터페이스로 코딩하고 연결하기 때문에 좋습니다. :)

자, 2 부, UI 논리를 도메인 논리와 분리하십시오. 글쎄, 이것은 잘 착용 된 경로이며 여기에서 MVP 패턴을 보는 것이 좋습니다. 정말 간단합니다.

각 컨트롤은 이제 View (VV에서 MVP)라고하며 위에서 필요한 대부분을 이미 다뤘습니다. 이 경우 컨트롤과 인터페이스입니다.

우리가 추가하는 것은 모델과 발표자뿐입니다.

이 모델에는 응용 프로그램 상태를 관리하는 논리가 포함되어 있습니다. 당신은 물건을 알고 있습니다, 그것은 사용자를 얻기 위해 데이터베이스로 가고, 사용자를 추가 할 때 데이터베이스에 쓰는 것입니다. 아이디어는이 모든 것을 다른 모든 것과 완전히 분리하여 테스트 할 수 있다는 것입니다.

발표자는 설명하기가 좀 더 까다 롭습니다. 모델과 뷰 사이에있는 클래스입니다. 뷰에 의해 생성되고 뷰는 앞에서 설명한 인터페이스를 사용하여 발표자에게 전달됩니다.

발표자는 자체 인터페이스를 가질 필요는 없지만 어쨌든 하나를 만들고 싶습니다. 발표자가 원하는 것을 명시 적으로 만듭니다.

따라서 발표자는 View가 사용자 목록을 얻는 데 사용할 ListOfAllUsers와 같은 메소드를 노출하거나, AddUser 메소드를 View에 놓고 발표자로부터 호출 할 수 있습니다. 나는 후자를 선호합니다. 이렇게하면 발표자가 원하는대로 목록 상자에 사용자를 추가 할 수 있습니다.

Presenter에는 CanEditUser와 같은 속성이 있으며 선택한 사용자를 편집 할 수 있으면 true를 반환합니다. 그러면 View는 알아야 할 때마다 쿼리합니다. 편집 가능한 것을 검은 색으로, 회색으로 만 읽을 수 있습니다. 기술적으로 UI에 중점을 둔 View의 결정은 사용자가 편집 가능한지 여부는 Presenter에 대한 것입니다. 발표자는 모델과 대화하기 때문에 알고 있습니다.

요약하면 MVP를 사용하십시오. Microsoft는 위에서 설명한 방식으로 MVP를 사용하는 SCSF (Smart Client Software Factory)를 제공합니다. 다른 것들도 많이합니다. 그것은 매우 복잡하고 나는 그들이 모든 것을하는 방식을 좋아하지 않지만 도움이 될 수 있습니다.


8

개인적으로 모든 것을 하나의 실행 파일로 묶지 않고 여러 어셈블리간에 서로 다른 관심 영역을 분리하는 것을 선호합니다.

일반적으로 나는 비즈니스 로직, GUI 코드 및 데이터 액세스 (데이터베이스 / 파일 액세스 / 네트워크 연결 등)가 아닌 응용 프로그램의 진입 점에 최소한의 코드를 유지하는 것을 선호합니다. 나는 일반적으로 진입 점 코드 (즉, 실행 파일)를

  • 모든 종속 어셈블리에서 다양한 응용 프로그램 구성 요소 생성 및 초기화
  • 전체 응용 프로그램이 의존하는 타사 구성 요소 구성 (예 : 진단 출력을위한 Log4Net)
  • 또한 예상치 못한 치명적 / 치명적 장애의 상황을 기록하는 데 도움이되는 기본 기능에 "모든 예외 포착 및 스택 추적 기록"유형의 코드 비트를 포함시킬 것입니다.

응용 프로그램 구성 요소 자체는 보통 작은 응용 프로그램에서 3 개 이상을 목표로합니다.

  • 데이터 액세스 계층 (데이터베이스 연결, 파일 액세스 등)-응용 프로그램에서 사용하는 지속성 / 저장 데이터의 복잡성에 따라 이러한 어셈블리가 여러 개있을 수 있습니다. 아마도 데이터베이스 처리를 위해 별도의 어셈블리를 만들 것입니다. 데이터베이스와 상호 작용할 때 복잡한 작업이 포함 된 어셈블리-예를 들어 잘못 설계된 데이터베이스가있는 stucx 인 경우 코드에서 DB 관계를 처리해야 할 수 있으므로 삽입 및 검색을 위해 여러 모듈을 작성하는 것이 좋습니다.

  • 로직 레이어-어플리케이션을 작동시키는 모든 결정과 알고리즘을 포함하는 주요 "고기". 이러한 결정은 GUI에 대해 전혀 아는 것이없고 (GUI가 있다고 말하는 사람은 누구입니까?), 데이터베이스에 대해서는 전혀 알아야합니다 (Huh? 데이터베이스가 있습니까? 왜 파일이 ​​아닙니까?). 잘 디자인 된 로직 레이어는 재 컴파일 할 필요없이 "리핑"되어 다른 응용 프로그램으로 드롭 될 수 있습니다. 복잡한 응용 프로그램에는 이러한 논리 어셈블리가 많이있을 수 있습니다 (응용 프로그램의 나머지 부분을 드래그하지 않고 '조각'을 찢어 내고 싶을 수 있기 때문에)

  • 프리젠 테이션 계층 (즉, GUI); 작은 응용 프로그램에는 모두 하나의 어셈블리로 들어갈 수있는 몇 개의 대화 상자가있는 단일 "기본 형식"이있을 수 있습니다. 더 큰 응용 프로그램에서는 GUI의 전체 기능 부분에 대한 별도의 어셈블리가있을 수 있습니다. 이 클래스는 사용자 상호 작용을 만드는 것 이상의 역할을 수행합니다. 기본 입력 유효성 검사, 애니메이션 처리 등을 포함하는 쉘 이상의 역할을합니다. "무언가를하는"이벤트 / 버튼 클릭은 전달됩니다. 로직 레이어 (따라서 프리젠 테이션 레이어에는 응용 프로그램 로직이 엄격하게 포함되지 않지만 GUI 레이어의 부담도 로직 레이어에 부과되지 않으므로 진행률 표시 줄이나 다른 멋진 것들도 프레젠테이션 어셈블리 / ies)

프레젠테이션, 논리 및 데이터 계층을 별도의 어셈블리로 분할하는 주된 이유는 다음과 같습니다. 데이터베이스 나 GUI없이 기본 응용 프로그램 논리를 실행할 수있는 것이 바람직하다고 생각합니다.

다시 말하면; 응용 프로그램과 동일한 방식으로 동작하지만 명령 줄 인터페이스 또는 웹 인터페이스를 사용하는 다른 실행 파일을 작성하려는 경우; 데이터베이스 스토리지를 파일 스토리지 (또는 다른 종류의 데이터베이스)로 교체 한 다음 주 응용 프로그램 논리를 전혀 만질 필요없이 그렇게 할 수 있습니다. 다른 데이터 모델을 연결 한 다음 "모두 연결"하면 준비가 완료됩니다.

당신은 "글쎄, 나는 절대로 그런 일을 하고 싶지 않을 것이므로 이것들을 바꿀 수 없다해도 문제가되지 않는다 "고 생각할 수도 있습니다 .-진정한 요점은 모듈 식 애플리케이션의 특징 중 하나는 '청크'를 추출하는 기능 (아무것도 다시 컴파일하지 않아도 됨) 및 다른 청크를 재사용하십시오. 이와 같은 코드를 작성하려면 일반적으로 설계 원칙에 대해 길고 열심히 생각해야합니다. 더 많은 인터페이스 작성에 대해 생각하고 다양한 SOLID 원칙의 균형에 대해 신중하게 생각해야합니다. 행동 주도 개발 또는 TDD와 같은 방식으로)

때때로 기존의 단일 코드 덩어리에서 이러한 분리를 달성하는 것은 약간 고통스럽고 신중한 리팩토링이 많이 필요합니다. 괜찮습니다. 점증 적으로 할 수 있어야합니다. 조립품이 너무 많고 결정하는 지점에 도달 할 수도 있습니다 다른 방향으로 되돌아 가서 물건을 다시 포장하기 시작하십시오.


4

폴더 구조에 따라 일반적으로 제안한 것은 정상입니다. 리소스에 대한 폴더를 추가해야 할 수도 있습니다 (때로는 사람들이 리소스를 생성하여 여러 언어를 지원하기 위해 각 리소스 세트가 ISO 언어 코드로 그룹화 됨), 이미지, 데이터베이스 스크립트, 사용자 기본 설정 (리소스로 처리되지 않은 경우), 글꼴 , 외부 dll, 로컬 dll 등

클래스를 추가 할 때 명명 규칙은 무엇입니까?

물론 각 클래스를 양식 외부에서 분리하려고합니다. 클래스 당 파일도 권장합니다 (예를 들어 MS는 EF 용으로 생성 된 코드에서는 그렇지 않습니다).

많은 사람들이 의미있는 짧은 명사를 복수형으로 사용합니다 (예 : 고객). 일부 ptrfer는 해당 데이터베이스 테이블의 단일 이름에 가깝도록 이름을 지정합니다 (객체와 테이블 사이에 1-1 맵핑을 사용하는 경우).

네이밍 클래스의 경우 많은 소스가 있습니다. .net 네이밍 규칙 및 프로그래밍 표준-모범 사례 및 / 또는 STOVF-C # 코딩 지침

수행 할 작업 기본 양식의 모든 코드가 Form1.cs로 끝나는 것은 아닙니다.

도우미 코드는 하나 이상의 도우미 클래스로 이동해야합니다. 그리드에 사용자 기본 설정을 적용하는 것과 같이 GUI 컨트롤에 매우 일반적인 다른 코드는 폼에서 제거되어 도우미 클래스에 추가되거나 해당 컨트롤을 하위 클래스로 분류하고 필요한 메서드를 만들 수 있습니다.

MS Windows Forms의 이벤트 동작 특성으로 인해 모호성과 노력을 추가하지 않고도 기본 양식에서 코드를 제거하는 데 도움이되는 것은 없습니다. 그러나 MVVM은 향후 프로젝트에서 선택할 수 있습니다 (예 : Windows Forms 용 MVVM 참조) .


2

MVP는 옵션으로 간주하여 프리젠 테이션 로직을 구성하는 데 도움이되므로 대기업 응용 프로그램의 모든 것입니다. 실제로는 앱 논리가 대부분 데이터베이스에 상주하므로 비즈니스 코드를 네이티브 코드로 실제로 작성해야하는 경우는 드물기 때문에 잘 구조화 된 프리젠 테이션 기능 만 있으면됩니다.

MVP와 유사한 구조는 원하는 경우 발표자 또는 컨트롤러 세트를 만들어 서로 조정하고 UI 또는 코드 뒤의 코드와 혼합하지 않습니다. 동일한 컨트롤러로 다른 UI를 사용할 수도 있습니다.

마지막으로 MVP 접근 방식과 함께 간단한 리소스 구성, 구성 요소 분리 및 IoC 및 DI로 중복 제거 기능 지정은 일반적인 실수와 복잡성을 피하고 적시에 제공되며 변경 될 수있는 시스템을 구축하는 열쇠를 제공합니다.


1

프로젝트의 구조는 프로젝트와 프로젝트의 크기에 따라 달라 지지만 폴더를 몇 개 추가 할 수 있습니다.

  • 공통 (클래스 포함 예 : 유틸리티)
  • DataAccess (sql 또는 사용중인 다른 데이터베이스 서버를 사용한 데이터 액세스와 관련된 클래스)
  • 스타일 (프로젝트에 CSS 파일이있는 경우)
  • 리소스 (예 : 이미지, 리소스 파일)
  • WorkFlow (있는 경우 워크 플로와 관련된 클래스)

모든 종류의 폴더에 양식을 넣을 필요는 없으며 그에 따라 양식의 이름을 바꾸십시오. 나는 어떤 상식이 자신보다 당신의 형태가 더 나은지 아무도 모릅니다.

이름 지정 규칙은 클래스가 "Hello World"메시지를 인쇄하는 경우 클래스 이름은 작업과 관련된 이름이어야하며 클래스의 적절한 이름은 HelloWorld.cs 여야합니다.

당신은뿐만 아니라 지역을 만들 수 있습니다

#region Hello 그런 다음 endregion끝납니다.

탭에 대한 클래스를 만들 수 있고, 확실하게 할 수 있으며, 마지막으로 가능한 한 코드를 재사용하는 것이 가장 좋습니다. 가장 좋은 방법은 메서드를 만들고 필요한 경우 다시 사용하는 것입니다.

책? 음.

각 프로젝트가 다르기 때문에 프로젝트 구조를 알려주는 책은 없습니다.

도움이 되었기를 바랍니다.

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