http://www.cnblogs.com/happyframework/p/3300170.html

目录

备注需求第一遍代码(重复的代码)第二遍代码(消除重复)备注

备注返回目录

不要重复自己,也不要重复别人,一旦养成了“拷贝和粘贴”的习惯,写程序的时候非常容易导致重复,好在一直暗示自己要稍后进行重构,本文给出一个重构的示例。

需求返回目录

需求:按照年、月和日显示销售数据,根据不同的周期类型,有三个问题需要注意:

  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 }

备注返回目录

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

 

消除Switch...Case的过程的更多相关文章

  1. 设计原则:消除Switch...Case的过程,可能有点过度设计了。

    备注 不要重复自己,也不要重复别人,一旦养成了“拷贝和粘贴”的习惯,写程序的时候非常容易导致重复,好在一直暗示自己要稍后进行重构,本文给出一个重构的示例. 需求 需求:按照年.月和日显示销售数据,根据 ...

  2. Java代码消除switch/case,if/else语句的几种实现方式

    转自:https://my.oschina.net/stefanzhlg/blog/372413 我们在平时的编码中,我们经常会遇到这样的情况: 使用过多的switch/case 或者 if else ...

  3. switch case 与 if

    case 在编程中偶尔使用到switch case语句,对于case语句的处理,出现了两种错误,现总结如下: case后必须是常量.布尔类型.字符(不能是字符串): case后如果是‘||’或者‘&a ...

  4. 为什么switch...case语句比if...else执行效率高

    在C语言中,教科书告诉我们switch...case...语句比if...else if...else执行效率要高,但这到底是为什么呢?本文尝试从汇编的角度予以分析并揭晓其中的奥秘. 第一步,写一个d ...

  5. 使用反射+策略模式代替项目中大量的switch case判断

    我这里的业务场景是根据消息类型将离线消息存入mongoDB不同的collection中.其中就涉及到大量的分支判断,为了增强代码的可读性和可维护性,对之前的代码进行了重构. 先对比一下使用反射+策略模 ...

  6. 知识扩展--if...else...与switch...case...的执行原理

    一.简述 编程语言中的条件分支结构有两种:if-else和switch-case,这两种条件分支之间可以相互转换,但是也存在一些区别,那么什么时候该用if-else,什么时候该用switch-case ...

  7. 浅析C/C++中的switch/case陷阱

    浅析C/C++中的switch/case陷阱 先看下面一段代码: 文件main.cpp #include<iostream> using namespace std; int main(i ...

  8. Java基础之循环语句、条件语句、switch case 语句

    Java 循环结构 - for, while 及 do...while 顺序结构的程序语句只能被执行一次.如果您想要同样的操作执行多次,,就需要使用循环结构. Java中有三种主要的循环结构: whi ...

  9. python中Switch/Case实现

    学习Python过程中,发现没有switch-case,过去写C习惯用Switch/Case语句,官方文档说通过if-elif实现.所以不妨自己来实现Switch/Case功能. 方法一 通过字典实现 ...

随机推荐

  1. Atitit.异步编程 java .net php python js 对照

    Atitit.异步编程 java .net php python js 的比較 1. 1.异步任务,异步模式,  APM模式,,  EAP模式, TAP 1 1.1.       APM模式: Beg ...

  2. c#数据库操作大全

    原文:c#数据库操作大全 1.提取单条记录 //using System.Data; //using System.Data.SqlClient;  using (SqlConnection cn = ...

  3. FPGA笔记-阅读.dat文件

    阅读.dat图像文件 .dat文件是matlab生成的图像文件 initial begin // Initialize Inputs CLK = 0; RST = 1; IMAGE_DATA = 0; ...

  4. CSS3+HTML5特效6 - 闪烁的文字

    先看效果 abcd 这个效果也比较简单,利用keyframes对文字的大小.透明度及颜色做循环显示. CSS <style> @-webkit-keyframes flash { 0%{ ...

  5. OracleServiceORCL服务不见了怎么办

    用管理员身份运行命令提示符(CMD) 然后输入“oradim -new -sid orcl”即可

  6. asp.net 给按钮 增加事件

    一个页面,有查询,审核,删除,取消审核 按钮,每次结尾 处都要 调用 Initdata方法,重新刷新数据 繁琐哇,我的解决方法是 protected void Page_Load(object sen ...

  7. JavaScript时间工具类

    /** * JavaScript日期工具类 * @author ZhangLp */ /** * 获取当前月的第一天 */ function getCurrentMonthFirst(){ var d ...

  8. Linux下tomcat管理查看控制台|杀死tomcat进程

    查看控制台 # tail -f catalina.out 脚本执行权限chmod u+x *.sh #看是否已经有tomcat在运行了 ps -ef |grep tomcat #如果有,用kill; ...

  9. Robotium源码分析之Instrumentation进阶-attach

    在分析Robotium的运行原理之前,我们有必要先搞清楚Instrumentation的一些相关知识点,因为Robotium就是基于Instrumentation而开发出来的一套自动化测试框架.鉴于之 ...

  10. extern用法汇总

    extern 在源文件A里定义的函数,在其他源文件中是看不见的(即不能訪问).为了在源文件B里能调用这个函数,应该在B的头部加上一个外部声明: extern   函数原型: 这样,在源文件B里也能够调 ...