设计原则:消除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在微观实践层面中的缘起.本质和具体操作方式, ...
随机推荐
- Django之管理权限
什么是权限: 谁对什么资源能做什么操作. 管理权限的实现有很多,这里实现一个最简单的管理权限的实现方式:rbac ( role based access control ) 实现的一个基本思路: ...
- Effective C++学习进阶版
记得前段时间又一次拿起<Effective C++>的时候,有种豁然开朗的感觉,所以翻出了我第一遍读时做的笔记.只做参考以及查阅之用.如有需要请参阅<Effective C++> ...
- sed实践
后来也找到一篇文章讲的很详细: http://www.cnblogs.com/ctaixw/p/5860221.html --------------------------------------- ...
- 用LR录制文件下载并随机产生文件名
用LR录制文件下载并随机产生文件名 {H.IY:X.Tn0 8h&~-D|6fV0Action()51Testing软件测试网GE$nV}s,R{51Testing软件测试网 }9sUS'q ...
- 久邦数码(3G门户)面试
久邦数码(3G门户)面试 1.数组和链表的区别(为什么数组带有索引) 2.数据库(手写选出一个公司年龄最大的100个员工) 3.一百个数查找一个数 利用二分查找一个数在最差的情况下至少比较多少次 4. ...
- Github 中提交项目到自己仓库的 gh-pages 分支
Github 中提交项目到自己仓库的gh-pages分支 cd cnblogs-theme/ git init git remote add origin git@github.com:hglibin ...
- 查找无序数组中第K大的数
思路: 利用快速排序的划分思想 可以找出前k大数,然后不断划分 直到找到第K大元素 代码: #include <iostream> #include <algorithm> # ...
- cogs——2098. Asm.Def的病毒
2098. Asm.Def的病毒 ★☆ 输入文件:asm_virus.in 输出文件:asm_virus.out 简单对比时间限制:1 s 内存限制:256 MB [题目描述] “这就 ...
- 邝斌带你飞之数论专题--Maximum GCD UVA - 11827
Given the N integers, you have to find the maximum GCD (greatest common divisor) of every possible p ...
- 「CSA49」Bunny on Number Line
「CSA49」Bunny on Number Line 题目大意:有一个人从0开始走,每次可以向前走一步或者回到1,那么会产生一个位置序列,其中给出 \(k\) 个位置是好的.定义一个位置序列是好的, ...