一、问题产生背景

当我们进行一系列处理时(员工工资核算,会员管理,计算器,优惠活动),会有很多相似的算法和处理过程,只是由于具体的算法的差异,导致必须不同处理。这些处理和客户端无关,我们可以把这些算法抽象,然后进行处理。之所以叫策略,基本含义就是

针对一个问题,采用一种处理策略。

二、策略模式的通常做法

1、将类似的算法分离,并抽象。

2、客户端选择算法(可以结合简单工厂模型,将矛盾转移到别的类里面)

3、Context调用算法。(Context是业务处理过程中的全部业务信息)

三、具体实例

我想要实现一个简单的计算器功能,首先我要面对的是+、-、*、/四则运算四个算法,我们可以将它抽象

    public abstract class AbstractCalculation
{
public void Show()
{
Console.WriteLine("这里是一个具体的计算");
} public abstract int Calculation(int iInputLeft, int iInputRight);
}

然后实现各个具体的运算(以+为示例,其它类似)

    public class Plus : AbstractCalculation
{
public override int Calculation(int iInputLeft, int iInputRight)
{
return iInputLeft + iInputRight;
}
}

这样我们的抽象工作就完成了。

下面我们写上下文类(Context,包含业务处理的全部信息,变量以及操作)

   public class Context
{
private int LeftOperator = ;
private int RightOperator = ;
private AbstractCalculation calculation = null; public Context(AbstractCalculation calculation, int iInputLeft, int iInputRight)
{
this.calculation = calculation;
LeftOperator = iInputLeft;
RightOperator = iInputRight;
} public int Calculate()
{
Console.WriteLine("Start Calculate");
try
{
return calculation.Calculation(LeftOperator, RightOperator);
}
catch (Exception ex)
{
throw ex;
} }
}

我们为了简化客户端,采用简单工厂模式将选择的矛盾转义到SimpleFactory中

   public class SimpleFactory
{
public static AbstractCalculation CreateCalculation(string oper)
{
switch (oper)
{
case "+":
return new Plus();
case "-":
return new Minus();
case "*":
return new Mutiply();
case "/":
return new Division();
default:
throw new Exception("不支持的操作!"); }
} }

最后进行组合调用:

    class Program
{
static void Main(string[] args)
{
Console.WriteLine("策略模式Demo"); int intResult = ;
int leftOperator;
int rightOperator;
string oper; while (true)
{
Console.WriteLine("请输入第一个操作数:");
leftOperator = Convert.ToInt32( Console.ReadLine());
Console.WriteLine("请输入操作符:");
oper = Console.ReadLine();
Console.WriteLine("请输入第二个操作数:");
rightOperator = Convert.ToInt32(Console.ReadLine()); AbstractCalculation calculation = SimpleFactory.CreateCalculation(oper);
Context context = new Context(calculation, leftOperator, rightOperator);
intResult = context.Calculate(); Console.WriteLine("{0}{1}{2}={3}",leftOperator,oper,rightOperator,intResult);
} }
}

四、设计模式分析

优点:a、将与具体业务无关的算法分离,便于添加。通常的,因为面向对象语言的最小单位是类,我们最好是添加算法类,而不是修改算法类。

b、由于context层将算法分离,因此可以添加一些其他渠道的参数,或者添加特殊处理,或者添加日志等。

缺点:并没有解决需要选择算法的矛盾,因此需要结合其他的设计模式处理,就像本利中添加了一个简单工厂,将矛盾从客户端转移,如果需要进一步处理,可以采用反射+配置文件的方式,或者依赖注入。

代码链接

设计模式のStrategyPattern(策略模式)----行为模式的更多相关文章

  1. 设计模式:策略模式(Strategy)

    定   义:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化, 不会影响到使用算法的客户. 示例:商场收银系统,实现正常收费.满300返100.打8折.......等不同收费 ...

  2. PHP设计模式之策略模式

    前提: 在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能.如查 找.排序等,一种常用的方法是硬编码(Hard Cod ...

  3. JavaScript设计模式之策略模式(学习笔记)

    在网上搜索“为什么MVC不是一种设计模式呢?”其中有解答:MVC其实是三个经典设计模式的演变:观察者模式(Observer).策略模式(Strategy).组合模式(Composite).所以我今天选 ...

  4. 乐在其中设计模式(C#) - 策略模式(Strategy Pattern)

    原文:乐在其中设计模式(C#) - 策略模式(Strategy Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 策略模式(Strategy Pattern) 作者:webabc ...

  5. JavaScript设计模式之策略模式

    所谓"条条道路通罗马",在现实中,为达到某种目的往往不是只有一种方法.比如挣钱养家:可以做点小生意,可以打分工,甚至还可以是偷.抢.赌等等各种手段.在程序语言设计中,也会遇到这种类 ...

  6. 【设计模式】【应用】使用模板方法设计模式、策略模式 处理DAO中的增删改查

    原文:使用模板方法设计模式.策略模式 处理DAO中的增删改查 关于模板模式和策略模式参考前面的文章. 分析 在dao中,我们经常要做增删改查操作,如果每个对每个业务对象的操作都写一遍,代码量非常庞大. ...

  7. [design-patterns]设计模式之一策略模式

    设计模式 从今天开始开启设计模式专栏,我会系统的分析和总结每一个设计模式以及应用场景.那么首先,什么是设计模式呢,作为一个软件开发人员,程序人人都会写,但是写出一款逻辑清晰,扩展性强,可维护的程序就不 ...

  8. 设计模式之——浅谈strategy模式(策略模式)

    strategy模式,即策略模式.个人觉得吧,策略模式更多的是一种思维方式. 首先我们要知道,为什么需要策略模式.举个例子,比如用程序输出今天下午去玩什么. PlayGame 玩游戏 package ...

  9. 设计模式(Python)-策略模式

    本系列文章是希望将软件项目中最常见的设计模式用通俗易懂的语言来讲解清楚,并通过Python来实现,每个设计模式都是围绕如下三个问题: 为什么?即为什么要使用这个设计模式,在使用这个模式之前存在什么样的 ...

  10. 设计模式入门,策略模式,c++代码实现

    // test01.cpp : Defines the entry point for the console application.////第一章,设计模式入门,策略模式#include &quo ...

随机推荐

  1. Python多线程的简单实现(生产者消费者模型)

    __author__ = "JentZhang" import time, threading, queue q = queue.Queue(maxsize=) # 声明队列 de ...

  2. win10下安装PHP_CodeSniffer 检查编码规范

    PHP CodeSniffer是PEAR中的一个用PHP5写的一个PHP的代码风格检测器,它根据预先设定好的PHP编码风格和规则,去检查应用中的代码风格情况是否有违反一组预先设置好的编码标准,内置了Z ...

  3. 【Spring】17、spring cache 与redis缓存整合

    spring cache,基本能够满足一般应用对缓存的需求,但现实总是很复杂,当你的用户量上去或者性能跟不上,总需要进行扩展,这个时候你或许对其提供的内存缓存不满意了,因为其不支持高可用性,也不具备持 ...

  4. Python 集合符号

    & 求交集 l 求并集 ^ 交叉补集 - 求差集 > = < =

  5. virtualbox中 Ubuntu挂载共享文件夹

    1. 进入 /mnt 目录 2. 新建目录 share 3. sudo mount -t vboxsf share /mnt/share(其中的第一个share是共享文件夹的名字) 4. 成功

  6. lua的多种实现方式(1-100的和)

    function add( a, b ) return a + b end -- print( add( 10, 20 ) ) function loopT( T ) for i, v in ipai ...

  7. 有状态(Stateful)与无状态(Stateless)

    1.有状态(Stateful): 有数据存储功能.有状态对象(Stateful Bean),就是有实例变量的对象,可以保存数据,类里面有成员变量,而且成员变量是可变的,是非线程安全的.在不同方法调用间 ...

  8. 小tips:JS数值之间的转换,JS中最大的Number是多少?,JS == 与 === 的区别

    JS数值之间的转换 Number(), parseInt(),parseFloat() Number()函数的转换规则如下: 1.如果boolean值,true和false将分别被转换为1和02.如果 ...

  9. 《JavaScript高级程序设计》笔记:引用类型(五)

    Object类型 创建object实例方法有两种.第一种方法使用new操作符后跟object构造函数.如下: var person=new Object(); person.name="Ni ...

  10. vue 构建项目遇到的问题

    1.我在打包完成后,打开index.html文件发现地址并没有携带路由. config下的 index.js 中的build命令的配置有一个属性叫assetsPublicPath,它的值为‘/’.意思 ...