一、问题产生背景

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

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

二、策略模式的通常做法

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. npm WARN enoent ENOENT: no such file or directory, open 'C:\Users\package.json'

    在使用 npm 命令安装常用的 Node.js web框架模块 express时出现: 解决方法是 在命令行切换到安装nodejs文件下的nodejs\node_modules\npm  后执行npm ...

  2. Java 学习笔记 执行外部命令 包装类 枚举类型

    执行外部命令 Runtime只能通过静态方法getRuntime获得,可以用来执行外部的命令 Runtime runtime = Runtime.getRuntime(); runtime.exec( ...

  3. Web Worker 初探

    什么是Web Worker? Web Worker 是Html5 提出的能够在后台运行javascript的对象,独立于其他脚本,不会影响页面的性能,也不会影响你继续对于页面进行操作.通俗点讲,就是后 ...

  4. crontab架构和格式

    crontab架构图 分时日月周*****my command(可以是一个linux命令,也可以是一个脚本文件,可以是shell格式也可以是python格式,也可是java格式.....) 按照格式编 ...

  5. date('Y-m-d H:i:s',time()) 与 date('Y-m-d h:i:s',time())区别是什么

    date('Y-m-d H:i:s',time()) 按24小时制 date('Y-m-d h:i:s',time()) 按12小时制

  6. python之把字符串形式的函数编译执行

    实现效果:执行字符串形式的函数 代码如下 # name = 'aaa' # data = [18,32,33] # def hellocute(): # return "name %s ,a ...

  7. cf24D. Broken robot(高斯消元)

    题意 题目链接 Sol 今天上午的A题.想出来怎么做了但是没时间写了qwq 思路很简单,首先把转移方程列一下,发现每一个位置只会从下一行/左右转移过来,而且第N行都是0,那么往下转移的都可以回带. 剩 ...

  8. ScrollView嵌套ListView、GridView,进入页面显示的位置并不是在最顶部,而是在中间部分问题

    在Android项目的开发中,经常会遇到一些布局,可能需要在ScrollView中嵌套ListView或.GridView来实现, 是在使用的过程总又遇到了一个新的问题,就是如果在ScrollView ...

  9. react 会员登录

    会员登录在我们的好多项目中都有用到,比如在后台管理系统,它的第一步就需要你进行登录,还有在我们常见的京东.淘宝.网易云音乐等一系列的软件上面都需要进行登录. 下面我们直接上代码 fetch(url,{ ...

  10. Angular调用Asp.net Core JWT Authentication接口

    基本思路是调用登录接口,获取token,使用token请求其他JWT接口: getHomeDetails(): Observable<HomeDetails> { let headers ...