2012-06-23 19 views
8

Hãy nói rằng chúng tôi có những hộp kiểm sau:Làm cách nào để làm cho mã này khô hơn?

  • FooCheckBox
  • BarCheckBox
  • BazCheckBox

Và những phương pháp:

  • Foo
  • Bar
  • Baz

Tôi muốn gọi mỗi phương thức chỉ khi hộp kiểm tra lại được chọn. Mã có thể trông giống như sau:

void DoWork() 
{ 
    if (FooCheckBox.Checked) 
    { 
     Foo(); 
     Console.WriteLine("Foo was called"); 
    } 

    if (BarCheckBox.Checked) 
    { 
     Bar(); 
     Console.WriteLine("Bar was called"); 
    } 

    if (BazCheckBox.Checked) 
    { 
     Baz(); 
     Console.WriteLine("Baz was called"); 
    } 
} 

Bây giờ, hãy xem xét thay vì 3 hộp kiểm và 3 phương pháp bạn có nhiều hơn. Làm thế nào bạn viết lại đoạn mã trên để làm cho nó thêm DRY?

+0

[Codereview.SE] (http://codereview.stackexchange.com/) phù hợp hơn với các câu hỏi cải thiện mã như câu hỏi này. – outis

Trả lời

7

Tôi sẽ nói trường hợp bạn đã trình bày, để nguyên trạng thái đó; bạn không muốn quá trừu tượng mà không có lý do chính đáng, vì nó có thể làm cho cơ sở mã ít bảo trì hơn. Tất nhiên bối cảnh là vấn đề mặc dù, và nó cuối cùng là một cuộc gọi phán xét.

Điều đó nói rằng, đây là cách tôi sẽ tiếp cận điều này. Tạo một bộ sưu tập trong đó mỗi mục chứa cả điều khiển và ủy nhiệm tác vụ. Sau đó lặp lại và thực hiện logic trên mỗi mục.

var items = new KeyValuePair<CheckBox, Action>[] { 
    new KeyValuePair<CheckBox,Action>(FooCheckBox, Foo), 
    new KeyValuePair<CheckBox,Action>(BarCheckBox, Bar), 
    new KeyValuePair<CheckBox,Action>(BazCheckBox, Baz) 
}; 

foreach (var item in items) 
{ 
    if (item.Key.Checked) 
    { 
     item.Value.Invoke(); 
     Console.WriteLine("Invoked " + item.Value.Method.Name); 
    } 
} 

Hoặc (có thể?) Tốt hơn sử dụng LINQ:

items.Where(item => item.Key.Checked).ToList().ForEach(item => new { 
    item.Value.Invoke(); 
    Console.WriteLine("Invoked " + item.Value.Method.Name); 
}); 
6

Bạn có thể sử dụng từ điển để theo kịp những hành động nào tham chiếu đến hộp kiểm nào. Sau đó, bạn có thể thực hiện các thao tác sau:

foreach(KeyValuePair<CheckBox, Action> kvp in Dict) 
{ 
    if(kvp.Key.Checked) 
     kvp.Value.Invoke(); 
} 
+0

'Hành động' ngụ ý không có đối số và void làm kiểu trả về. – Odys

+2

@odyodyodys Vì vậy, làm 3 phương pháp được đề xuất bởi OP. –

+0

Chính xác. Các cuộc gọi Method của anh ta ngụ ý không có đối số hoặc kiểu trả về. Mặc dù bạn có thể dễ dàng thay thế một hàm thay cho Hành động nếu bạn cần. – MrWuf

2

Nó có thể được thực hiện theo cách sau:

void DoWork() 
{ 
    Func<Action, string, Tuple<Action, string>> toT = 
     (a, s) => new Tuple<Action, string>(a, s); 

    var map = new Dictionary<CheckBox, Tuple<Action, string>> 
    { 
     {FooCheckBox, toT(Foo, "Foo")}, 
     {BarCheckBox, toT(Bar, "Bar")}, 
     {BazCheckBox, toT(Baz, "Baz")}, 
    }; 

    foreach (var x in map.Keys) 
     if (x.Checked) 
     { 
      map[x].Item1(); 
      Console.WriteLine(map[x].Item2 + " was called"); 
     } 
} 

Nhưng tôi nghĩ rằng đôi khi là không phải là rất khô chỉ là được.

0

tôi sẽ tạo ra một Dictionary với <CheckBox, Func> và lặp qua mỗi giá trị:

Dictionary<CheckBox, Func> checkboxes = new Dictionary<CheckBox, Func>(); 
void Init() 
{ 
    checkboxes.Add(FooCheckBox, Foo); 
    checkboxes.Add(BarCheckBox, Bar); 
    checkboxes.Add(BazCheckBox, Baz); 
} 

void DoWork() 
{ 
    foreach (KeyValuePair<CheckBox, Func> checkbox in checkboxes) 
    { 
     if (checkbox.Key.Checked) 
     { 
      checkbox.Value(); 
      Console.WriteLine("{0} was called", checkbox.Text); 
     } 
    } 
} 
4

vì đơn giản tôi sẽ đi với

void DoWork() 
{ 
    DoIfChecked(FooCheckBox, Foo, "Foo as Called"); 
    DoIfChecked(BarCheckBox, Bar, "Bar as Called"); 
    DoIfChecked(BazCheckBox, Baz, "Baz as Called"); 
} 
void DoIfChecked(CheckBox checkBox, Action action, string message) 
{ 
    if (checkBox.IsChecked) 
    { 
     action(); 
     Console.WriteLine(message); 
    } 
} 

nhưng bạn có thể làm điều gì đó với phần tin nhắn nếu nó là đơn giản, và tôi có thể ném một số lỗi kiểm tra tùy thuộc vào ngữ cảnh cục bộ.