2015-04-20 18 views
6

Tái cấu trúc là tốt, nhưng đôi khi nó không phải là dễ dàng như vậy để làm việc ra làm thế nào để refactor và thực sự cho dù một cái gì đó thực sự có thể được refactored!C# Tái cấu trúc hai phương pháp gần giống hệt nhau

Tôi có một số phương pháp gần như giống hệt nhau - tôi có thể cấu trúc lại chúng nhưng một phần của quá trình tái cấu trúc nằm ngoài logic của tôi.

Dưới đây là hai phương pháp un-refactored:

private void projectToolStripMenuItem_Click(object sender, EventArgs e) 
    { 
     if (projectToolStripMenuItem.Checked) 
     { 
      projectToolStripMenuItem.Checked = false; 
      if (!projectForm.IsDisposed) projectForm.Hide(); 
     } 
     else 
     { 
      if (projectForm.IsDisposed) 
       projectForm = new frmProject(); 
      projectForm.Show(dockPanel, DockState.DockRight); 
      projectToolStripMenuItem.Checked = true; 
     } 

    } 

    private void logginToolStripMenuItem_Click(object sender, EventArgs e) 
    { 
     if (logginToolStripMenuItem.Checked) 
     { 
      logginToolStripMenuItem.Checked = false; 
      if (!outputForm.IsDisposed) outputForm.Hide(); 
     } 
     else 
     { 
      if (outputForm.IsDisposed) 
       outputForm = new frmOutput(); 
      outputForm.Show(dockPanel, DockState.DockBottom); 
      logginToolStripMenuItem.Checked = true; 
     } 
    } 

Với Refactoring tôi sẽ có được một phương pháp như thế này mà các phương pháp trước đó un-refactored sẽ gọi

private void refactoredMethod(TooStripMenuItem menuItem, DockContent frmName) 
{ 

     if (menuItem.Checked) 
     { 
      menuItem.Checked = false; 
      if (!frmName.IsDisposed) frmName.Hide(); 
     } 
     else 
     { 
      if (frmName.IsDisposed) 
       frmName= new frmProject(); // Still Problematic 
      frmName.Show(dockPanel, DockState.DockRight); 
      menuItem.Checked = true; 
     } 
    } 

Vì vậy, những gì chúng ta có một hầu phương pháp tái cấu trúc hoàn toàn - với một vấn đề, Làm cách nào tôi có thể biết được form Tôi muốn khởi tạo biến số frmName nào?

+1

bạn đang mong đợi gì xảy ra với DockState.Dock *? Liệu phương pháp được cấu trúc lại có phải là DockState.DockRight không? Hoặc nó sẽ thay đổi tùy thuộc vào loại bạn đang sử dụng? – Cubia

+0

@Cubia đã đánh dấu bạn để chỉ ra điều này. Mặc dù tôi nhận thấy sai lầm ngay khi tôi thử nghiệm câu trả lời: P –

Trả lời

8

Bạn có thể đặt phương thức chung và tận dụng lợi thế của ràng buộc chung new().

private TForm refactoredMethod<TForm>(TooStripMenuItem menuItem, TForm frmName) where TForm : Form, new() 
{ 
    if (menuItem.Checked) 
    { 
     menuItem.Checked = false; 
     if (!frmName.IsDisposed) frmName.Hide(); 
    } 
    else 
    { 
     if (frmName.IsDisposed) 
      frmName= new TForm(); 
     frmName.Show(dockPanel, DockState.DockRight); 
     menuItem.Checked = true; 
    } 
    return frmName; 
} 

Vì vậy, bạn có thể gọi nó như

projectForm = refactoredMethod<frmProject>(projectToolStripMenuItem, projectForm); 

Một hạn chế là hình thức của bạn nên có một constructor parameterless công cộng. Nếu bạn có một Form với hàm tạo tham số, bạn có thể vượt qua Func<TForm> cho phương pháp của mình hoạt động như một phương pháp nhà máy.

+0

frmName.Show() có hai tham số khác nhau trong mỗi phương thức. Làm thế nào bạn sẽ làm cho công việc đó? – Cubia

+1

Do nhiệm vụ 'frmName' phải bằng ref hoặc được trả về. – Alex

+0

@ Alex Tôi không thích 'ref' Tôi sẽ cập nhật bài đăng của mình để sử dụng giá trị trả lại. Cảm ơn. –

1

Vượt qua một nhà máy để phương pháp này, như thế này:

private void RefactoredMethod(..., Func<TypeOfItemToCreate> creator) 
{ 
    ... 
    if (frmName.IsDisposed) 
      frmName = creator(); 
} 

Yêu cầu duy nhất là cả hai lớp bạn tạo cần phải có một số giao diện phổ biến hay lớp cơ sở.

1

Tôi thấy đã có câu trả lời nhưng vẫn muốn viết thêm điều gì đó. Tôi tin rằng tái cấu trúc là nhiều hơn bạn mô tả ở đây. Một điều đang thay đổi tên cho hàm, một là đặt mã vào hàm riêng biệt. Cũng nên nhớ rằng không có phép tái cấu trúc thích hợp nếu không có các phép thử đơn vị thích hợp.

Trong ví dụ của bạn, bạn đang trộn các hàm mức cao với hàm mức thấp (thay đổi sai thành đúng, tạo đối tượng, v.v), cũng không tự mô tả.

Vì vậy, có rất nhiều thứ để làm trong điều khoản của refactoring:

void hideForm(TForm form){ 
    if(!form.IsDisposed){ 
     form.Hide(); 
    } 
} 

void showFormInDockPanel<TForm>(TForm form, DockPanel dockPanel){ 
    if(form.IsDisposed){ 
     form = new TForm(); 
    } 
    form.Show(dockPanel, DockState.DockRight); 
} 

void toggleFormAndMenuItem<TForm>(TForm form, TooStripMenuItem menuItem){ 
    if(menuItem.checked){ 
     hideForm(form); 
    } 
    else { 
     showFormInDockPanel<TForm>(form, dockPanel); 
    } 

    menuItem.checked = !menuItem.checked; 
} 

private void projectToolStripMenuItem_Click(object sender, EventArgs e){ 
    toggleFormAndMenuItem<frmProject>(projectToolStripMenuItem, projectForm); 
} 
Các vấn đề liên quan