消除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功能. 方法一 通过字典实现 ...
随机推荐
- jquery+css3打造一款ajax分页插件
原文:[原创]jquery+css3打造一款ajax分页插件 最近公司的项目将好多分页改成了ajax的前台分页以前写的分页插件就不好用了,遂重写一个 支持IE6+,但没有动画效果如果没有硬需求,个人认 ...
- JS正则替换字符串
1.只替换第一次出现的字符: text.replace(/javascript/i, "JavaScript"); //正则用//来将正则包起来 i表示区分大小写 2.全局替换: ...
- 事半功倍之StyleCop(一)
事半功倍之StyleCop(一) 前言 曾几何时,你是否在看别人代码的时候总是在抱怨代码没有注释,命名不规范,代码风格不统一,代码可读性差?是否有一个适合团队开发规范的检查工具? 答案就是大名鼎鼎的S ...
- android学习8(ListView高级使用)
ListView在android更开放的,于是继续ListView说明使用. 首先创建一个android项目,项目名为ListViewTest. ListView的简单使用 改动布局文件,改动后代码例 ...
- Kafka spring 集成
下载配置kafka参考该链接:http://www.cnblogs.com/super-d2/p/4534323.html pom.xml: <dependency> <groupI ...
- VMWare 11安装操作系统 - 初学者系列 - 学习者系列文章
在2010年的时候,我写过一篇关于VMWare的安装操作系统的博文.但是今天在QQ群里有人问起VMWare安装操作系统的问题,虽然回答了,但是回头看了下当时那篇博文,决定重新写一文. 首先要获取VMW ...
- html5 Geolocation(地理位置定位)学习
1.html5 Geolocation html5 Geolocation API 使用很简单,请求一个位置信息,如果用户同意,浏览器会返回一个位置信息,该位置是通过用户的底层设备(手机,电脑) 提供 ...
- Unity3D第三人称摄像机控制脚本
好久没有敲Blog该.感谢您的留言.注意.私人信件和其他支持,但我似乎没有办法继续自己曾经写了一篇博客系列,因为我在网上找到有关unity3D太少的内容,U3D相关的文章!.. 第三人称视角 第三人称 ...
- ReviewBoard安装和配置说明
眼下部门还没有採用Pair Programming那种时时刻刻都在review代码的工作方式,代码Review多採用走查方式.即代码写完后召开一个Code Review的Meeting,集中时间和经验 ...
- Failed to issue method call: Unit mysql.service failed to load: No such file or directory解决的方式
Failed to issue method call: Unit mysql.service failed to load: No such file or directory解决的方式 作者:ch ...