2016-08-19 7 views
-2

이것은 코드 자체에 대한 것이 아니라 코드 구조에서의 우수 사례에 관한 질문입니다. 현재 WinForms 응용 프로그램을 만들고 있는데 몇 시간 후에 기본 양식에 130 줄의 코드가 들어 있습니다. 그다지 많지 않을 수도 있지만 이것은 이벤트 처리 만 포함합니다. 기본적으로 모든 것을위한 별도의 클래스 파일을 가짐으로써이 정확한 상황을 피하려고했기 때문에 ...하지만 지금 모든 컨트롤과 이벤트는 내 주요 코드를 읽기가 어렵게 만듭니다.기본 서식 유지 규칙 - 규칙

이제는 주제가 상당히 놀랍습니다. 사용자 지정 컨트롤을 만들고 큰 부분으로 양식을 분할하는 것과 같은 방법에 대한 아이디어가 있습니다. 이것에 대한 일종의 모범 사례가 있습니까? 사용자 상호 작용의 80 %가 여기에서 발생하면 기본 양식을 어떻게 깨끗하게 유지합니까? 또한 권장할만한 프로젝트 (코드가 아닌)를 구조화하는 기본적인 지침이 있습니까?

감사 (희망이 유효한 질문 자격)!

편집 : 코드를 추가하기로 결정했습니다. 리던던트가 보이니?

public partial class MainForm : Form 
{ 
    string currentFilter = "all"; 

    public MainForm() 
    { 
     InitializeComponent(); 
    } 
    private void MainForm_Load(object sender, System.EventArgs e) 
    { 
     RefreshGenres(); 
     RefreshMovies(currentFilter); 
    } 

    private void addToolStripMenuItem_Click(object sender, System.EventArgs e) 
    { 
     var fAdd = new AddNewForm(); 

     fAdd.SetDesktopLocation(MousePosition.X, MousePosition.Y); 
     fAdd.ShowDialog(); 
    } 

    private void refreshToolStripMenuItem_Click(object sender, System.EventArgs e) 
    { 
     RefreshGenres(); 
     RefreshMovies(currentFilter); 
    } 

    private void addCategoryToolStripMenuItem_Click(object sender, System.EventArgs e) 
    { 
     tvCategories.Nodes.Add(new TreeNode("category")); 
     tvCategories.Nodes[tvCategories.Nodes.Count - 1].BeginEdit(); 
    } 
    private void tvCategories_AfterLabelEdit(object sender, NodeLabelEditEventArgs e) 
    { 
     var genre = e.Label; 
     var writer = new Writer(); 
     writer.AddGenre(e.Label); 

    } 


    private void everythingToolStripMenuItem_Click(object sender, System.EventArgs e) 
    { 
     EraseData("all"); 
    } 
    private void clearGenres_Click(object sender, System.EventArgs e) 
    { 
     EraseData("genres"); 
    } 
    private void clearMovies_Click(object sender, System.EventArgs e) 
    { 
     EraseData("movies"); 
    } 
    private void EraseData(string eraseThis) 
    { 
     DialogResult r = MessageBox.Show("Are you sure?\nLost data can NOT be retrieved.", "Clear Data", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); 

     var cmdText = ""; 

     if (r == DialogResult.Yes) 
     { 
      switch (eraseThis) 
      { 
       case "all": 
        cmdText = "TRUNCATE TABLE MOVIES GENRES"; 
        break; 

       case "movies": 
        cmdText = "TRUNCATE TABLE MOVIES"; 
        break; 

       case "genres": 
        cmdText = "TRUNCATE TABLE GENRES"; 
        break; 
      } 
      conn.Open(); 
      using (var cmd = conn.CreateCommand()) 
      { 
       cmd.CommandText = cmdText; 
       cmd.ExecuteNonQuery(); 
      } 
      conn.Close(); 
     } 
    } 


    private void RefreshGenres() 
    { 
     tvCategories.Nodes.Clear(); 

     var reader = new Reader(); 
     var genres = reader.GetGenreList(); 

     foreach (string str in genres) 
     { 
      tvCategories.Nodes.Add(str); 
     } 
    } 
    private void RefreshMovies(string filter) 
    { 
     lvMovies.Items.Clear(); 

     var reader = new Reader(); 
     var movies = reader.GetMovieList(filter); 

     foreach (ListViewItem item in movies) 
     { 
      lvMovies.Items.Add(item); 
     } 
     reader.conn.Close(); 

    } 

    private void tvCategories_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) 
    { 
     currentFilter = e.Node.Text; 
     RefreshMovies(currentFilter); 
    } 
} 
+1

주요 목표는 UI 로직, 즉 비즈니스 로직의 이벤트를 작성하는 것입니다. 따라서 이벤트 핸들러는 실제 로직을 제어하는 ​​로직 객체에 대한 호출을 포함하지 않아야합니다. – TaW

답변

1

나는 문제가 여기에 코드의 길이,하지만 당신은 많은 다른 것들을 혼합되어 있고 일관된 방식으로 이벤트를 처리하지 않는 사실이 아니라고 생각. 다음은 내가 바꿀 주요 사항입니다.

EraseData :이 방법은 DB 연결을 열어 사용하며 일반적으로 피해야합니다 (DB의 내용을 변경하면 UI 코드가 수정 될 수 있습니다) , WinForm 코드는 노출되는 데이터의 출처를 알 수 없습니다. EraseData를 Writer 클래스에 추가하는 것이 좋습니다.

RefreshMovies :이 두 가지 방법이 본질적으로 동일한 경우에도 RefreshGenres와 완전히 다릅니다. 일부 UI 컨트롤에 추가되는 데이터 목록을 얻고 있습니다. RefreshGenres는 좋아 보이지만 RefreshMovies를 보면 즉시이 메소드에서 열지 않은 연결이 닫히고 있음을 알 수 있습니다. 아마 당신은 Reader 클래스에서 열었을 것입니다, 그러나 그것은 당신이 그것을 닫아야 만했던 곳이기도합니다. 사실 conn이 개인적인 것이 더 낫습니다. UI는 데이터가 DB, 텍스트 파일 또는 사용자 입력에서 왔는지 여부를 알 필요가 없습니다. 또한 Reader의 GetGenreList는 문자열 목록을 반환하지만 GetMovieList는 ListViewItem 목록을 반환합니다. ListViewItem은 사용자의 특정 UI 구현과 관련이 있기 때문에 좋지 않습니다. 즉, Reader 구현을 WPF 또는 웹 응용 프로그램에서 사용할 수 없습니다. Reader에서 가져온 일반 데이터를 사용하여 ListViewItem을 RefreshMovies에 만들어야합니다.

+0

감사합니다! 물론 주 형식에서 DB 연결을 열지는 못하지만, 코딩 규칙을 연구 할 때 읽은 내용이 아닙니다. 연결을 끊기로 한 이유는 독자 클래스에 각각 3 가지 방법이 있기 때문입니다. 연결을 열고 닫지 만 그 중 하나는 실제로 다른 메서드를 사용합니다.이 메서드는 완료되면 첫 번째 메서드에 대한 연결을 닫습니다. 그렇습니다, 나는 왜 그것이 '이상적이지 않은지 : D – momo