备注

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

需求

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

  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. Django之管理权限

    什么是权限: 谁对什么资源能做什么操作. 管理权限的实现有很多,这里实现一个最简单的管理权限的实现方式:rbac   ( role based access control ) 实现的一个基本思路: ...

  2. Effective C++学习进阶版

    记得前段时间又一次拿起<Effective C++>的时候,有种豁然开朗的感觉,所以翻出了我第一遍读时做的笔记.只做参考以及查阅之用.如有需要请参阅<Effective C++> ...

  3. sed实践

    后来也找到一篇文章讲的很详细: http://www.cnblogs.com/ctaixw/p/5860221.html --------------------------------------- ...

  4. 用LR录制文件下载并随机产生文件名

    用LR录制文件下载并随机产生文件名 {H.IY:X.Tn0 8h&~-D|6fV0Action()51Testing软件测试网GE$nV}s,R{51Testing软件测试网 }9sUS'q  ...

  5. 久邦数码(3G门户)面试

    久邦数码(3G门户)面试 1.数组和链表的区别(为什么数组带有索引) 2.数据库(手写选出一个公司年龄最大的100个员工) 3.一百个数查找一个数 利用二分查找一个数在最差的情况下至少比较多少次 4. ...

  6. Github 中提交项目到自己仓库的 gh-pages 分支

    Github 中提交项目到自己仓库的gh-pages分支 cd cnblogs-theme/ git init git remote add origin git@github.com:hglibin ...

  7. 查找无序数组中第K大的数

    思路: 利用快速排序的划分思想 可以找出前k大数,然后不断划分 直到找到第K大元素 代码: #include <iostream> #include <algorithm> # ...

  8. cogs——2098. Asm.Def的病毒

    2098. Asm.Def的病毒 ★☆   输入文件:asm_virus.in   输出文件:asm_virus.out   简单对比时间限制:1 s   内存限制:256 MB [题目描述] “这就 ...

  9. 邝斌带你飞之数论专题--Maximum GCD UVA - 11827

    Given the N integers, you have to find the maximum GCD (greatest common divisor) of every possible p ...

  10. 「CSA49」Bunny on Number Line

    「CSA49」Bunny on Number Line 题目大意:有一个人从0开始走,每次可以向前走一步或者回到1,那么会产生一个位置序列,其中给出 \(k\) 个位置是好的.定义一个位置序列是好的, ...