設計原則:消除Switch...Case的過程,可能有點過度設計了。


備注

不要重復自己,也不要重復別人,一旦養成了“拷貝和粘貼”的習慣,寫程序的時候非常容易導致重復,好在一直暗示自己要稍后進行重構,本文給出一個重構的示例。

需求

需求:按照年、月和日顯示銷售數據,根據不同的周期類型,有三個問題需要注意:

  1. 默認的日期范圍不同
  2. 圖表中顯示的格式不同
  3. 默認的模擬數據不同(發布環境會使用真實的數據)

如下圖:

 

第一遍代碼(重復的代碼)

最愛的拷貝和粘貼。

默認的日期范圍不同

 1         private void ResetStartDateAndEndDate()
 2         {
 3             this.EndDate = DateTime.Now;
 4 
 5             switch (_currentCircle)
 6             {
 7                 case "":
 8                     this.StartDate = this.EndDate.AddMonths(-1);
 9                     break;
10                 case "":
11                     this.StartDate = this.EndDate.AddMonths(-12);
12                     break;
13                 case "":
14                     this.StartDate = this.EndDate.AddMonths(-12 * 3);
15                     break;
16             }
17 
18             this.StartDate = this.StartDate.AddDays(1);
19         }

圖表中顯示的格式不同

 1         public string DisplayDate
 2         {
 3             get
 4             {
 5                 switch (this.Cycle)
 6                 {
 7                     case "":
 8                         return this.Date.ToString("yyyy-MM-dd");
 9                     case "":
10                         return this.Date.ToString("yyyy-MM");
11                     case "":
12                         return this.Date.ToString("yyyy");
13                     default:
14                         throw new InvalidOperationException("周期類型不匹配");
15                 }
16             }
17         }

默認的模擬數據不同

 1         public IEnumerable<SalesViewModel> Find(string cycle, DateTime startDate, DateTime endDate)
 2         {
 3             switch (cycle)
 4             {
 5                 case "":
 6                     return new List<SalesViewModel>
 7                     {
 8                         new SalesViewModel{ Date = DateTime.Now.AddDays(-2).AddDays(1), Total = 100, Cycle = cycle },
 9                         new SalesViewModel{ Date = DateTime.Now, Total = 200, Cycle = cycle }
10                     };
11                 case "":
12                     return new List<SalesViewModel>
13                     {
14                         new SalesViewModel{ Date = DateTime.Now.AddMonths(-2).AddDays(1), Total = 100, Cycle = cycle },
15                         new SalesViewModel{ Date = DateTime.Now, Total = 200, Cycle = cycle }
16                     };
17                 case "":
18                     return new List<SalesViewModel>
19                     {
20                         new SalesViewModel{ Date = DateTime.Now.AddYears(-2).AddDays(1), Total = 100, Cycle = cycle },
21                         new SalesViewModel{ Date = DateTime.Now, Total = 200, Cycle = cycle }
22                     };
23                 default:
24                     return new List<SalesViewModel>();
25             }
26         }

第二遍代碼(消除重復)

“門面類型+多態+私有內部類”消除重復

  1 using System;
  2 using System.Net;
  3 using System.Windows;
  4 using System.Windows.Controls;
  5 using System.Windows.Documents;
  6 using System.Windows.Ink;
  7 using System.Windows.Input;
  8 using System.Windows.Media;
  9 using System.Windows.Media.Animation;
 10 using System.Windows.Shapes;
 11 using System.Collections.Generic;
 12 
 13 namespace Marking.Dashboard.Infrastructures
 14 {
 15     public static class CycleTypeHelper
 16     {
 17         private static Dictionary<string, CycleType> _CycleTypeMaps = new Dictionary<string, CycleType>
 18         {
 19             { "", new DayCycleType() },
 20             { "", new MonthCycleType() },
 21             { "", new YearCycleType() }
 22         };
 23 
 24         public static IEnumerable<string> CircleTypes
 25         {
 26             get
 27             {
 28                 return _CycleTypeMaps.Keys;
 29             }
 30         }
 31 
 32         public static DateTime GetDefaultStartDate(string cycleType, DateTime endDate)
 33         {
 34             return _CycleTypeMaps[cycleType].GetDefaultStartDate(endDate);
 35         }
 36 
 37         public static string GetDisplayDateString(string cycleType, DateTime date)
 38         {
 39             return _CycleTypeMaps[cycleType].GetDisplayDateString(date);
 40         }
 41 
 42         public static IEnumerable<DateTime> SimulateDates(string cycleType, DateTime startDate, DateTime endDate)
 43         {
 44             return _CycleTypeMaps[cycleType].SimulateDates(startDate, endDate);
 45         }
 46 
 47         private abstract class CycleType
 48         {
 49             public abstract DateTime GetDefaultStartDate(DateTime endDate);
 50 
 51             public abstract string GetDisplayDateString(DateTime date);
 52 
 53             public abstract IEnumerable<DateTime> SimulateDates(DateTime startDate, DateTime endDate);
 54         }
 55 
 56         private class YearCycleType : CycleType
 57         {
 58             public override DateTime GetDefaultStartDate(DateTime endDate)
 59             {
 60                 return endDate.AddMonths(-12 * 3);
 61             }
 62 
 63             public override string GetDisplayDateString(DateTime date)
 64             {
 65                 return date.ToString("yyyy");
 66             }
 67 
 68             public override IEnumerable<DateTime> SimulateDates(DateTime startDate, DateTime endDate)
 69             {
 70                 for (var i = startDate; i <= endDate; i = i.AddYears(1))
 71                 {
 72                     yield return i;
 73                 }
 74             }
 75         }
 76 
 77         private class MonthCycleType : CycleType
 78         {
 79             public override DateTime GetDefaultStartDate(DateTime endDate)
 80             {
 81                 return endDate.AddMonths(-12);
 82             }
 83 
 84             public override string GetDisplayDateString(DateTime date)
 85             {
 86                 return date.ToString("yyyy-MM");
 87             }
 88 
 89             public override IEnumerable<DateTime> SimulateDates(DateTime startDate, DateTime endDate)
 90             {
 91                 for (var i = startDate; i <= endDate; i = i.AddMonths(1))
 92                 {
 93                     yield return i;
 94                 }
 95             }
 96         }
 97 
 98         private class DayCycleType : CycleType
 99         {
100             public override DateTime GetDefaultStartDate(DateTime endDate)
101             {
102                 return endDate.AddMonths(-1);
103             }
104 
105             public override string GetDisplayDateString(DateTime date)
106             {
107                 return date.ToString("MM-dd");
108             }
109 
110             public override IEnumerable<DateTime> SimulateDates(DateTime startDate, DateTime endDate)
111             {
112                 for (var i = startDate; i <= endDate; i = i.AddDays(1))
113                 {
114                     yield return i;
115                 }
116             }
117         }
118     }
119 }

備注

完成第一遍后,差點不想進行重構了,戰勝自己非常不容易,繼續努力。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM