• 设计原则:消除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 }

    备注

    完成第一遍后,差点不想进行重构了,战胜自己非常不容易,继续努力。

  • 相关阅读:
    mongodb分布式查询
    MongoDB JAVA API Filters
    mongodb.conf配置文件详解
    mongodb安装配置
    Elasticsearch-2.3.x填坑之路
    C++对象模型详解
    关于虚函数的那些事儿
    关于B树的一些总结
    动态规划问题
    C中的qsort函数和C++中的sort函数的理解与使用
  • 原文地址:https://www.cnblogs.com/happyframework/p/3300170.html
Copyright © 2020-2023  润新知