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

第一遍代码(重复的代码)
最爱的拷贝和粘贴。
默认的日期范围不同
private void ResetStartDateAndEndDate()
{
this.EndDate = DateTime.Now; switch (_currentCircle)
{
case "日":
this.StartDate = this.EndDate.AddMonths(-);
break;
case "月":
this.StartDate = this.EndDate.AddMonths(-);
break;
case "年":
this.StartDate = this.EndDate.AddMonths(- * );
break;
} this.StartDate = this.StartDate.AddDays();
}
图表中显示的格式不同
public string DisplayDate
{
get
{
switch (this.Cycle)
{
case "日":
return this.Date.ToString("yyyy-MM-dd");
case "月":
return this.Date.ToString("yyyy-MM");
case "年":
return this.Date.ToString("yyyy");
default:
throw new InvalidOperationException("周期类型不匹配");
}
}
}
默认的模拟数据不同
public IEnumerable<SalesViewModel> Find(string cycle, DateTime startDate, DateTime endDate)
{
switch (cycle)
{
case "日":
return new List<SalesViewModel>
{
new SalesViewModel{ Date = DateTime.Now.AddDays(-).AddDays(), Total = , Cycle = cycle },
new SalesViewModel{ Date = DateTime.Now, Total = , Cycle = cycle }
};
case "月":
return new List<SalesViewModel>
{
new SalesViewModel{ Date = DateTime.Now.AddMonths(-).AddDays(), Total = , Cycle = cycle },
new SalesViewModel{ Date = DateTime.Now, Total = , Cycle = cycle }
};
case "年":
return new List<SalesViewModel>
{
new SalesViewModel{ Date = DateTime.Now.AddYears(-).AddDays(), Total = , Cycle = cycle },
new SalesViewModel{ Date = DateTime.Now, Total = , Cycle = cycle }
};
default:
return new List<SalesViewModel>();
}
}
第二遍代码(消除重复)
“门面类型+多态+私有内部类”消除重复
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic; namespace Marking.Dashboard.Infrastructures
{
public static class CycleTypeHelper
{
private static Dictionary<string, CycleType> _CycleTypeMaps = new Dictionary<string, CycleType>
{
{ "日", new DayCycleType() },
{ "月", new MonthCycleType() },
{ "年", new YearCycleType() }
}; public static IEnumerable<string> CircleTypes
{
get
{
return _CycleTypeMaps.Keys;
}
} public static DateTime GetDefaultStartDate(string cycleType, DateTime endDate)
{
return _CycleTypeMaps[cycleType].GetDefaultStartDate(endDate);
} public static string GetDisplayDateString(string cycleType, DateTime date)
{
return _CycleTypeMaps[cycleType].GetDisplayDateString(date);
} public static IEnumerable<DateTime> SimulateDates(string cycleType, DateTime startDate, DateTime endDate)
{
return _CycleTypeMaps[cycleType].SimulateDates(startDate, endDate);
} private abstract class CycleType
{
public abstract DateTime GetDefaultStartDate(DateTime endDate); public abstract string GetDisplayDateString(DateTime date); public abstract IEnumerable<DateTime> SimulateDates(DateTime startDate, DateTime endDate);
} private class YearCycleType : CycleType
{
public override DateTime GetDefaultStartDate(DateTime endDate)
{
return endDate.AddMonths(- * );
} public override string GetDisplayDateString(DateTime date)
{
return date.ToString("yyyy");
} public override IEnumerable<DateTime> SimulateDates(DateTime startDate, DateTime endDate)
{
for (var i = startDate; i <= endDate; i = i.AddYears())
{
yield return i;
}
}
} private class MonthCycleType : CycleType
{
public override DateTime GetDefaultStartDate(DateTime endDate)
{
return endDate.AddMonths(-);
} public override string GetDisplayDateString(DateTime date)
{
return date.ToString("yyyy-MM");
} public override IEnumerable<DateTime> SimulateDates(DateTime startDate, DateTime endDate)
{
for (var i = startDate; i <= endDate; i = i.AddMonths())
{
yield return i;
}
}
} private class DayCycleType : CycleType
{
public override DateTime GetDefaultStartDate(DateTime endDate)
{
return endDate.AddMonths(-);
} public override string GetDisplayDateString(DateTime date)
{
return date.ToString("MM-dd");
} public override IEnumerable<DateTime> SimulateDates(DateTime startDate, DateTime endDate)
{
for (var i = startDate; i <= endDate; i = i.AddDays())
{
yield return i;
}
}
}
}
}
备注
完成第一遍后,差点不想进行重构了,战胜自己非常不容易,继续努力。
设计原则:消除Switch...Case的过程,可能有点过度设计了。的更多相关文章
- 消除Switch...Case的过程
http://www.cnblogs.com/happyframework/p/3300170.html 目录 备注需求第一遍代码(重复的代码)第二遍代码(消除重复)备注 备注返回目录 不要重复自己, ...
- Java代码消除switch/case,if/else语句的几种实现方式
转自:https://my.oschina.net/stefanzhlg/blog/372413 我们在平时的编码中,我们经常会遇到这样的情况: 使用过多的switch/case 或者 if else ...
- SOA 实现:服务设计原则
http://www.ibm.com/developerworks/cn/webservices/ws-soa-design/ 引言 面向服务的体系结构(Service-Oriented Archit ...
- JAVA设计模式总结之六大设计原则
从今年的七月份开始学习设计模式到9月底,设计模式全部学完了,在学习期间,总共过了两篇:第一篇看完设计模式后,感觉只是脑子里面有印象但无法言语.于是决定在看一篇,到9月份第二篇设计模式总于看完了,这一篇 ...
- 设计原则:开-闭原则(Open-Closed Principle, OCP)
开-闭原则就是软件实体应当对扩展开放,对修改关闭.(Software entities should be open for extension,but closed for modification ...
- 《设计模式之美》 <03>面向对象、设计原则、设计模式、编程规范、重构,这五者有何关系?
面向对象 现在,主流的编程范式或者是编程风格有三种,它们分别是面向过程.面向对象和函数式编程.面向对象这种编程风格又是这其中最主流的.现在比较流行的编程语言大部分都是面向对象编程语言.大部分项目也都是 ...
- 【面像对象编程OOP】五种设计原则 Solid
"面向对象设计五大原则"和良性依赖原则在应付变化方面的作用. SOLID(单一功能.开闭原则.里氏替换.接口隔离以及依赖反转) 单一职责原则(Single-Resposibilit ...
- Java程序员应当知道的10个面向对象设计原则
面向对象设计原则是OOPS编程的核心, 但我见过的大多数Java程序员热心于像Singleton (单例) . Decorator(装饰器).Observer(观察者) 等设计模式,而没有把足够多的注 ...
- 微观SOA:服务设计原则及其实践方式
大 量互联网公司都在拥抱SOA和服务化,但业界对SOA的很多讨论都比较偏向高大上.本文试图从稍微不同的角度,以相对接地气的方式来讨论SOA, 集中讨论SOA在微观实践层面中的缘起.本质和具体操作方式, ...
随机推荐
- golang之结构体和方法
结构体的定义 结构体是将零个或者多个任意类型的命令变量组合在一起的聚合数据类型.每个变量都叫做结构体的成员. 其实简单理解,Go语言的结构体struct和其他语言的类class有相等的地位,但是GO语 ...
- python基础(8)--迭代器、生成器、装饰器
1.迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退.另外,迭代器的一大优 ...
- hive学习(五) 应用案例
1.实现struct数据结构例子 1.1创建student表 create table student( id int, info struct<name:string,age:int> ...
- MVC – 9.mvc整体请求流程
1.请求管道 2~5微软自己的验证,我们一般不用. 在全局配置文件中-已经配置一个路由过滤器-为第7个事件注册了路由方法 1.在application_start中向静态路由表注册了路由数据,在管道第 ...
- cocos2dx2.x 创建项目
cocos2d-x下载地址:http://www.cocos2d-x.org/download 2.0之后的创建项目比较easy了 第一步,首先 cd cocos2d-x-2.2.1/tools/pr ...
- Hadoop案例(七)MapReduce中多表合并
MapReduce中多表合并案例 一.案例需求 订单数据表t_order: id pid amount 1001 01 1 1002 02 2 1003 03 3 订单数据order.txt 商品信息 ...
- vim编码相关
与vim编码相关的四个配置: encoding:vim核心编码,所有vim交换区,信息提示区都用这个编码.打开文件的编码如果是其他编码,会自动转换为核心编码,保存时再转回文件编码. fileencod ...
- LeetCode 137. Single Number II(只出现一次的数字 II)
LeetCode 137. Single Number II(只出现一次的数字 II)
- 牛客练习赛9 F - 珂朵莉的约数
题目描述 珂朵莉给你一个长为n的序列,有m次查询 每次查询给两个数l,r 设s为区间[l,r]内所有数的乘积 求s的约数个数mod 1000000007 输入描述: 第一行两个正整数n,m第二行一个长 ...
- C++ 四种显示转换
转自:http://www.jellythink.com/archives/205 (果冻想) 前言 这篇文章总结的是C++中的类型转换,这些小的知识点,有的时候,自己不是很注意,但是在实际开发中 ...