备注

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

需求

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

  1. 默认的日期范围不同
  2. 图表中显示的格式不同
  3. 默认的模拟数据不同(发布环境会使用真实的数据)

如下图:

第一遍代码(重复的代码)

最爱的拷贝和粘贴。

默认的日期范围不同

         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的过程,可能有点过度设计了。的更多相关文章

  1. 消除Switch...Case的过程

    http://www.cnblogs.com/happyframework/p/3300170.html 目录 备注需求第一遍代码(重复的代码)第二遍代码(消除重复)备注 备注返回目录 不要重复自己, ...

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

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

  3. SOA 实现:服务设计原则

    http://www.ibm.com/developerworks/cn/webservices/ws-soa-design/ 引言 面向服务的体系结构(Service-Oriented Archit ...

  4. JAVA设计模式总结之六大设计原则

    从今年的七月份开始学习设计模式到9月底,设计模式全部学完了,在学习期间,总共过了两篇:第一篇看完设计模式后,感觉只是脑子里面有印象但无法言语.于是决定在看一篇,到9月份第二篇设计模式总于看完了,这一篇 ...

  5. 设计原则:开-闭原则(Open-Closed Principle, OCP)

    开-闭原则就是软件实体应当对扩展开放,对修改关闭.(Software entities should be open for extension,but closed for modification ...

  6. 《设计模式之美》 <03>面向对象、设计原则、设计模式、编程规范、重构,这五者有何关系?

    面向对象 现在,主流的编程范式或者是编程风格有三种,它们分别是面向过程.面向对象和函数式编程.面向对象这种编程风格又是这其中最主流的.现在比较流行的编程语言大部分都是面向对象编程语言.大部分项目也都是 ...

  7. 【面像对象编程OOP】五种设计原则 Solid

    "面向对象设计五大原则"和良性依赖原则在应付变化方面的作用. SOLID(单一功能.开闭原则.里氏替换.接口隔离以及依赖反转) 单一职责原则(Single-Resposibilit ...

  8. Java程序员应当知道的10个面向对象设计原则

    面向对象设计原则是OOPS编程的核心, 但我见过的大多数Java程序员热心于像Singleton (单例) . Decorator(装饰器).Observer(观察者) 等设计模式,而没有把足够多的注 ...

  9. 微观SOA:服务设计原则及其实践方式

    大 量互联网公司都在拥抱SOA和服务化,但业界对SOA的很多讨论都比较偏向高大上.本文试图从稍微不同的角度,以相对接地气的方式来讨论SOA, 集中讨论SOA在微观实践层面中的缘起.本质和具体操作方式, ...

随机推荐

  1. 初窥Linux 之 最常用20条命令

    玩过Linux的人都会知道,Linux中的命令的确是非常多,但是玩过Linux的人也从来不会因为Linux的命令如此之多而烦恼,因为我们只需要掌握我们最常用的命令就可以了.当然你也可以在使用时去找一下 ...

  2. **CodeIgniter系列 添加filter和helper

    filter: 使用CI的hooks来实现filter. 1.在system/application/config/config.php中,把enable_hooks的值改为TRUE $config[ ...

  3. day5 常用模块json和pickle

    json 和 pickle json和pickle是用于字符串序列化和反序列化的过程,我们在存储和使用的时候,经常把列表存入文件,读取的时候我们还想以列表的形式读取.就需要使用json和pickle. ...

  4. 9 行 javascript 代码获取 QQ 群成员

    昨天看到一条微博:「22 行 JavaScript 代码实现 QQ 群成员提取器」. 本着好奇心点击进去,发现没有达到效果,一是 QQ 版本升级了,二是博客里面的代码也有些繁琐. 于是自己试着写了一个 ...

  5. 转:vs无法调试解决方案

    转:http://blog.csdn.net/jean7155/article/details/48223739 vs中无法加入断点进行调试的解决方案 [ 1] 以前也遇到过同样的问题,但没有问个为什 ...

  6. UVA12995 Farey Sequence [欧拉函数,欧拉筛]

    洛谷传送门 Farey Sequence (格式太难调,题面就不放了) 分析: 实际上求分数个数就是个幌子,观察可以得到,所求的就是$\sum^n_{i=2}\phi (i)$,所以直接欧拉筛+前缀和 ...

  7. 基于rsync方式的文件备份

    rsync 是一个快速增量文件传输工具,它可以用于在同一主机备份内部的备分,我们还可以把它作为不同主机网络备份工具之用.本文主要讲述的是如何自架rsync服 务器,以实现文件传输.备份和镜像.相对ta ...

  8. hdu 1180 诡异的楼梯(优先队列)

    Hogwarts正式开学以后,Harry发现在Hogwarts里,某些楼梯并不是静止不动的,相反,他们每隔一分钟就变动一次方向.  比如下面的例子里,一开始楼梯在竖直方向,一分钟以后它移动到了水平方向 ...

  9. WP SyntaxHighlighter 初探

    继上篇文章发布后,我随即去网上找了下博客园.CSDN他们用的高亮工具,果然都是用的别人的,SyntaxHighlighter.去官网上看了下,很强大,包含各种经典配色以及多语言.要想在wordpres ...

  10. FastReport.Net使用:[24]其他控件(邮政编码(Zip Code),网格文本(Cellular Text)以及线性刻度尺(Linear Gauge))

    邮政编码(Zip Code) Zip Code仅支持数字(0~9) Zip Code支持数据列绑定,表达式,文本等模式 可通过修改SegmentCount属性的值来确定Zip Code的位数. 数字右 ...