一、问题产生背景

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

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

二、策略模式的通常做法

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. [angularjs] angularjs系列笔记(四)控制器

    Scope作用域 Scope作用域是应用在HTML视图和Js控制器之间的纽带 Scope是一个对象,有可用的属性和方法 根作用域 所有的应用都有一个$rootScope,它可以作用在ng-app指令包 ...

  2. HbuilderX 常用快捷键

    最新2019.3.30版本已经添加idea的快捷键,就不需要再额外记住HbuilderX的快捷键啦~ 链接 输入a,按下tab 加粗 ctrl+B 换行 需要换行的那一行后面加2个空格(或者按下tab ...

  3. Spring Boot 2.0 升级指南

    Spring Boot 2.0 升级指南 前言 Spring Boot已经发布2.0有5个月多,多了很多新特性,一些坑也慢慢被填上,最近有空,就把项目中Spring Boot 版本做了升级,顺便整理下 ...

  4. JS取出两个数组中的不同或相同元素

    1.取出两个数组的不同元素 var arr1 = [0,1,2,3,4,5]; var arr2 = [0,4,6,1,3,9]; function getArrDifference(arr1, ar ...

  5. angular 动态取到的html片段 在页面的展示

    写个过滤器 xxx.filter( 'to_trusted', ['$sce', function ($sce) { return function (text) { return $sce.trus ...

  6. CF607B Zuma(区间dp)

    题意 题目链接 Sol 裸的区间dp,转移的时候判一下两个字符是否相等即可 #include<bits/stdc++.h> #define Pair pair<int, int> ...

  7. 【20190221】HTTP-URI与URL

    URI(uniform resource identifier)统一资源标识符是由某个协议方案表示的资源的定位标识符, URI 用字符串标识某一互联网资源,而 URL 表示资源的地点(互联网上所处的位 ...

  8. ICML 2018 | 从强化学习到生成模型:40篇值得一读的论文

    https://blog.csdn.net/y80gDg1/article/details/81463731 感谢阅读腾讯AI Lab微信号第34篇文章.当地时间 7 月 10-15 日,第 35 届 ...

  9. Mysql 常用数据类型

    double:浮点型,double(5,2) 表示最多5位,必须包含两位小数,最大值是 999.99 char:定长字符串类型,char(10) 表示必须放 10 的字节,没有就用空格补充 varch ...

  10. View体系第二篇:View滑动

    View滑动的基本思想:当点击事件传到View时,系统记下触摸点的坐标,手指移动时系统记下触摸后的坐标并计算出偏移量,然后根据偏移量修正View坐标. 实现View滑动共有6种方法:layout()方 ...