重构第11天 使用策略代替Switch(Switch to Strategy)
理解:策略就是平常设计模式中所说的策略模式。因为当你有一个庞大的switch方法的时候,每一次新加一个条件,都要去修改这个方法,这样耦合性太高,不易维护也不易扩展。这样我们就可以使用策略的设计模式,使得每一种情况都封装在自己的类中,来提高扩展性和降低耦合性。
详解:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace _31DaysRefactor
{ public class ClientCode
{ public decimal CalculateShipping()
{
ShippingInfo shippinginfo = new ShippingInfo(); return shippinginfo.CalclateShippingAmount(State.Alaska);
} } public enum State
{
Alaska,
NewYork,
Florida
} public class ShippingInfo
{ public decimal CalclateShippingAmount(State shipToState)
{
switch (shipToState)
{
case State.Alaska:
return GetAlaskaShippingAmount();
case State.NewYork:
return GetNewYorkShippingAmount();
case State.Florida:
return GetFloridaShippingAmount();
default:
return 0m;
}
} private decimal GetAlaskaShippingAmount()
{
return 15m;
} private decimal GetNewYorkShippingAmount()
{
return 10m;
} private decimal GetFloridaShippingAmount()
{
return 3m;
}
}
}
为了完成switch重构,我们需要把每一种条件封装成一个独立的类,然后这些类提取出一个公共接口,每个类都实现该接口。下次如果你想添加新的条件,只需要新增一个实现该公共接口的类即可。
这里我们提取出一个公共接口IShippingCalculation,这个类包含一个方法decimal Caculate()和一个属性 State State { get; }。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace _31DaysRefactor
{ public class ClientCode
{ public decimal CalculateShipping()
{
IShippingInfo shippingInfo = new ShippingInfo();
return shippingInfo.CalculateShippingAmount(State.Alaska);
} } public enum State
{
Alaska,
NewYork,
Florida
} public interface IShippingCalculation
{
decimal Caculate();
} public interface IShippingInfo
{
decimal CalculateShippingAmount(State state);
} public class ShippingInfo : IShippingInfo
{
private IDictionary<State, IShippingCalculation> ShippingCalculations { get; set; } public ShippingInfo()
{
ShippingCalculations = new Dictionary<State, IShippingCalculation>(){
{State.Alaska,new AlaskShippingCaculation()},
{State.Florida,new FloridaShippingCaculation()},
{State.NewYork,new NewYorkShippingCaculation()}
};
} public decimal CalculateShippingAmount(State shipToState)
{
return this.ShippingCalculations[shipToState].Caculate();
} } public class AlaskShippingCaculation : IShippingCalculation
{
public State State { get { return State.Alaska; } } public decimal Caculate()
{
return 15m;
}
} public class NewYorkShippingCaculation : IShippingCalculation
{
public State State { get { return State.NewYork; } } public decimal Caculate()
{
return 10m;
}
} public class FloridaShippingCaculation : IShippingCalculation
{
public State State { get { return State.Florida; } } public decimal Caculate()
{
return 3m;
}
}
}
重构第11天 使用策略代替Switch(Switch to Strategy)的更多相关文章
- 重构改善既有代码设计--重构手法11:Move Field (搬移字段)
你的程序中,某个字段被其所驻类之外的另一个类更多的用到.在目标类建立一个新字段,修改源字段的所有用户,令它们改用新字段. 动机:在类之间移动状态和行为,是重构过程中必不可少的措施.随着系 ...
- 11.best fields策略(dis_max参数设置)
主要知识点 常规multi-field搜索结果分析 dis_max参数设置 一.为帖子数据增加content字段 POST /forum/article/_bulk { "u ...
- 模板模式与策略模式/template模式与strategy模式/行为型模式
模板模式 模版模式,又被称为模版方法模式,它可以将工作流程进行封装,并且对外提供了个性化的控制,但主流程外界不能修改,也就是说,模版方法模式中,将工作的主体架构规定好,具体类可以根据自己的需要,各自去 ...
- 重构11-Switch to Strategy(Switch到策略模式)
重构没有固定的形式,多年来我使用过不同的版本,并且我敢打赌不同的人也会有不同的版本. 该重构适用于这样的场景:switch语句块很大,并且会随时引入新的判断条件.这时,最好使用策略模式将每个条件封装到 ...
- 使用策略模式重构switch case 代码
目录 1.背景 2.案例 3.switch…case…方式实现 4.switch…case…带来的问题 5.使用策略模式重构switch…case…代码 6.总结 1.背景 之前在看<重构 ...
- 转-PHP 设计模式 之策略模式 应用场景 Strategy Pattern
一.前言 关于设计模式的文章,园子里实在是太多太多,而且讲解的也非常精彩,那为什么我还要在这里记录下这篇文章?本文以实际项目应用“自己动手写工具--XSmartNote”为切入点,来讲述策略模式的应用 ...
- C#重构经典全面汇总
C#重构经典全面汇总 1. 封装集合 概念:本文所讲的封装集合就是把集合进行封装,仅仅提供调用端须要的接口. 正文:在非常多时候,我们都不希望把一些不必要的操作暴露给调用端,仅仅须要给它所须要的操作 ...
- 策略模式设计模式(Strategy)摘录
23种子GOF设计模式一般分为三类:创建模式.结构模型.行为模式. 创建模式抽象的实例.一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将 ...
- 31天重构学习笔记(java版本)
准备下周分享会的内容,无意间看到.net版本的重构31天,花了两个小时看了下,可以看成是Martin Fowler<重构>的精简版 原文地址:http://www.lostechies.c ...
随机推荐
- Generating a new ASP.NET session in the current HTTPContext
void regenerateId() { System.Web.SessionState.SessionIDManager manager = new System.Web.SessionState ...
- SQL的主键和外键约束
SQL的主键和外键的作用: 外键取值规则:空值或参照的主键值. (1)插入非空值时,如果主键表中没有这个值,则不能插入. (2)更新时,不能改为主键表中没有的值. (3)删除主键表记录时,你可以在建外 ...
- iOS开发——项目实战总结&带你看看Objective-C的精髓
带你看看Objective-C的精髓 1:接口与实现 @interface...@end @implementation...@end @class 接口(头文件) 实现文件 向前引用 注:类别通过增 ...
- ASP.NET MVC应用require.js实践
这里有更好的阅读体验和及时的更新:http://pchou.info/javascript/asp.net/2013/11/10/527f6ec41d6ad.html Require.js是一个支持j ...
- 深入解析DC/OS 1.8 – 高可靠的微服务及大数据管理平台
深入解析DC/OS 1.8 – 高可靠的微服务及大数据管理平台 大家好,欢迎大家参加这次DC/OS的技术分享. 先做个自我介绍,刘超,Linker Networks首席架构师,Open DC/OS社区 ...
- mac下python实现vmstat
mac下没有linux/unix 的vmstat,只有vm_stat; sh-3.2# vm_statMach Virtual Memory Statistics: (page size of 409 ...
- 使用U盘代替光盘来刻录ISO镜像文件的方法
原文链接: http://jingyan.baidu.com/article/d3b74d64aa4a6a1f77e60932.html 1.以管理员身份运行UltraISO,点击“文件”菜单下的“打 ...
- (笔记)Linux内核学习(十)之虚拟文件系统概念
虚拟文件系统 虚拟文件系统:内核子系统VFS,VFS是内核中文件系统的抽象层,为用户空间提供文件系统相关接口: 通过虚拟文件系统,程序可以利用标准Linux文件系统调用在不同的文件系统中进行交互和操作 ...
- mac 自动配置java版本
首先输入命令:vi .bash_profile ,添加如下内容: # Mac默认 JDK (Mac默认自带了一个jdk6版本) export JAVA_6_HOME=`/usr/libexec/jav ...
- const ,static,inline
const: 1 定义变量 ,如下写法都可以: TYPE const ValueName = value; const TYPE ValueName = value; ...