备注

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

需求

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

  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. xss 过滤

    一. xss过滤 用户通过Form获取展示在终端, 提交数据,Form验证里面加入xss验证(对用户提交的内容验证是否有关键标签) from django.conf.urls import url f ...

  2. Effective STL 阅读笔记: Item 3: Make copying cheap and correct for objects in containers

    容器 (Containers) 用来存储对象 (Objects), 但是被存储的对象却并非原原本本是你给他的那一个, 而是你指定对象的一个拷贝.而后续对该容器内存储对象的操作,大多也是基于拷贝的. 拷 ...

  3. bitbucket SSH 生成

    在bitbucket设置ssh的方法: 1.运行ssh-keygen. 2.一路enter,直接到结束. 3 seeting 中Bitbucket选择.ssh/id_rsa.pub文件

  4. python开发学习-day02(元组、字符串、列表、字典深入)

    s12-20160109-day02 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: ...

  5. Python全栈开发之4、内置函数、文件操作和递归

    转载请注明出处http://www.cnblogs.com/Wxtrkbc/p/5476760.html 一.内置函数 Python的内置函数有许多,下面的这张图全部列举出来了,然后我会把一些常用的拿 ...

  6. c# winform读取及发送串口信号

    请参考C#的API文档:https://docs.microsoft.com/zh-cn/dotnet/api/system.io.ports.serialport?redirectedfrom=MS ...

  7. python动态获取对象的属性和方法 (转)

    转自未知,纯个人笔记使用 首先通过一个例子来看一下本文中可能用到的对象和相关概念. #coding:utf-8 import sys def foo():pass class Cat(object): ...

  8. OOD沉思录 --- 类和对象的关系 --- 使用关系

    使用关系 对象A的方法MethodA使用了B的方法MethodB,则表示A对B存在使用关系 使用关系的最关键问题在于,A如何找到B,存在6种方案 方案一: A包含了B,B作为一个成员定义在A的类中,那 ...

  9. 洛谷P2730 魔板 [广搜,字符串,STL]

    题目传送门 魔板 题目背景 在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板.这是一张有8个大小相同的格子的魔板: 1 2 3 4 8 7 6 5 题目描述 我们知道魔板的每一个方格都有 ...

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

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