消除Switch...Case的过程
http://www.cnblogs.com/happyframework/p/3300170.html
目录
备注返回目录
不要重复自己,也不要重复别人,一旦养成了“拷贝和粘贴”的习惯,写程序的时候非常容易导致重复,好在一直暗示自己要稍后进行重构,本文给出一个重构的示例。
需求返回目录
需求:按照年、月和日显示销售数据,根据不同的周期类型,有三个问题需要注意:
- 默认的日期范围不同
- 图表中显示的格式不同
- 默认的模拟数据不同(发布环境会使用真实的数据)
如下图:

第一遍代码(重复的代码)返回目录
最爱的拷贝和粘贴。
默认的日期范围不同

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的过程的更多相关文章
- 设计原则:消除Switch...Case的过程,可能有点过度设计了。
备注 不要重复自己,也不要重复别人,一旦养成了“拷贝和粘贴”的习惯,写程序的时候非常容易导致重复,好在一直暗示自己要稍后进行重构,本文给出一个重构的示例. 需求 需求:按照年.月和日显示销售数据,根据 ...
- Java代码消除switch/case,if/else语句的几种实现方式
转自:https://my.oschina.net/stefanzhlg/blog/372413 我们在平时的编码中,我们经常会遇到这样的情况: 使用过多的switch/case 或者 if else ...
- switch case 与 if
case 在编程中偶尔使用到switch case语句,对于case语句的处理,出现了两种错误,现总结如下: case后必须是常量.布尔类型.字符(不能是字符串): case后如果是‘||’或者‘&a ...
- 为什么switch...case语句比if...else执行效率高
在C语言中,教科书告诉我们switch...case...语句比if...else if...else执行效率要高,但这到底是为什么呢?本文尝试从汇编的角度予以分析并揭晓其中的奥秘. 第一步,写一个d ...
- 使用反射+策略模式代替项目中大量的switch case判断
我这里的业务场景是根据消息类型将离线消息存入mongoDB不同的collection中.其中就涉及到大量的分支判断,为了增强代码的可读性和可维护性,对之前的代码进行了重构. 先对比一下使用反射+策略模 ...
- 知识扩展--if...else...与switch...case...的执行原理
一.简述 编程语言中的条件分支结构有两种:if-else和switch-case,这两种条件分支之间可以相互转换,但是也存在一些区别,那么什么时候该用if-else,什么时候该用switch-case ...
- 浅析C/C++中的switch/case陷阱
浅析C/C++中的switch/case陷阱 先看下面一段代码: 文件main.cpp #include<iostream> using namespace std; int main(i ...
- Java基础之循环语句、条件语句、switch case 语句
Java 循环结构 - for, while 及 do...while 顺序结构的程序语句只能被执行一次.如果您想要同样的操作执行多次,,就需要使用循环结构. Java中有三种主要的循环结构: whi ...
- python中Switch/Case实现
学习Python过程中,发现没有switch-case,过去写C习惯用Switch/Case语句,官方文档说通过if-elif实现.所以不妨自己来实现Switch/Case功能. 方法一 通过字典实现 ...
随机推荐
- IronPython和C#交互
IronPython和C#交互 IronPython是一个.NET平台上的Python实现,包括了完整的编译器.执行引擎与运行时支持,能够与.NET已有的库无缝整合到一起. IronPython已经很 ...
- 【Head First Javascript】学习笔记0——自己制作chm参考手册素材
变量声明:var 常量声明:const 数据格式转换: 1.转换函数 parseInt(A):把字符串A转换成整数:其中A为只包含数字的字符串 parseFloat(A):把字符串A转换成浮点数:其中 ...
- 部署中遇到的问题-UWSGI(一)
假设uwsgi错误中提示 *** no app loaded. going in full dynamic mode *** 运行 [plain] view plaincopy aptitude in ...
- android 反编译(dex 和 odex),非脑残转帖,绝对可靠
Android 反编译 反编译odex文件(比如framework.odex),若是反编译dex,直接第4步 1.因为反编译odex的工具在D:\Develop tools\android反编译工具\ ...
- Win7搭建NodeJs开发环境
Win7搭建NodeJs开发环境以及HelloWorld展示—图解 Windows 7系统下搭建NodeJs开发环境(NodeJs+WebStrom)以及Hello World!展示,大体思路如下:第 ...
- 利用svn自动同步更新到网站服务器 -- 网摘
首先在服务器上安装VisualSVN Server ,根据提示选好安装的路径,一路确定.安装好后运行VisualSVN Server ,在Repositories上点击右键,选择create New ...
- JavaScript时间工具类
/** * JavaScript日期工具类 * @author ZhangLp */ /** * 获取当前月的第一天 */ function getCurrentMonthFirst(){ var d ...
- sax(用于处理XML事件驱动的推模型)解析例子
SAX解析 Java程序如下: import org.xml.sax.helpers.DefaultHandler; import javax.xml.parsers.SAXParser; impor ...
- Monkey源码分析之事件源
上一篇文章<Monkey源码分析之运行流程>给出了monkey运行的整个流程,让我们有一个概貌,那么往后的文章我们会尝试进一步的阐述相关的一些知识点. 这里先把整个monkey类的结构图给 ...
- ASP.NET4.0新特性
原文:ASP.NET4.0新特性 在以前试用VS2010的时候已经关注到它在Web开发支持上的一些变化了,为此我还专门做了一个ppt,当初是计划在4月12日那天讲的,结果因为莫名其妙的原因导致没有语音 ...