策略模式的介绍

在软件开发中也常常遇到这样一种情况:实现某一功能可以有多种算法或者策略,我们根据实际情况选择不同的算法策略来完成该功能。例如:排序算法,可以使用插入排序,归并排序,冒泡排序等。

针对这种情况,一种常规的方法是将多种算法写在一个类中。例如,需要提供多种排序算法,可以将这些算法写到一个类中,每一个方法对应一个具体的排序算法;当然,也可以将这些排序算法封装在一个统一的方法中,通过if….else….或者case等条件语句来选择具体的算法。这两种实现方法我们称之为硬编码。然而。当很多算法集中在一个类中时,这个类就会变得臃肿,这个类的维护成本会变高,在维护时也更容易引发错误。如果需要增加一种新的排序算法,需要修改封装算法类的源代码。这就明显维护了我们上面所说的OCP原则和单一职责原则。

如果将这些算法或者策略抽象出来,提供一个统一的接口,不同的算法或者策略不同的实现类,这样在程序客户端就可以通过注入不同的实现对象来实现算法或者策略的动态替换,这种模式的可扩展性,可维护性也就更高,这就是我准备说的策略模式。

策略模式的定义

策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们可以相互替换。策略模式让算法独立于使用它的客户而独立变化。

策略模式的使用场景

(1) 针对同一类型问题的多种处理方式,仅仅是具体行为有差别时
(2) 需要安全地封装多种同一类型的操作时
(3) 出现同样抽象有多个子类,而有需要使用if-else或者switch-case来选择具体子类时。

策略模式的简单实现

下面我们以北京坐公共交通工具的费用计算来演示一个简单示例。在2014年12月28号之后,北京提高公交价格,不再是单一票价制,而是分段计价,也就是乘坐距离越远,价格越高。显然公交车和地铁的价格计算方式是不一样的,但是,我们的示例中需要计算乘不同出行工具的成本,下面我们就用策略模式进行代码演示

首先我们需要定义一个抽象的价格计算接口,这里命名为CaculateStrategy,具体代码如下:

/**
* 计算接口
* /
public interface CaculateStrategy{
/**
* 按距离计算价格
* @param km 公里
* @return 返回价格
int caculatePrice(int km);
}

对于每一种出行方式我们都有一个独立的计算策略类,这些策略都实现了CaculateStrategy接口,例如下面是公交车和地铁的计算策略类:

//公交车的价格计算策略
public class BusStrategy implements CaculateStrategy{//北京公交车,十公里之内一元钱,超过十公里之后再加一元钱可以乘5公里
//@param Km 公里
// @return
@Override
public int CaculatePrice(int km){
//超过10公里的总距离
int extraTotal=km-10;
//超过距离是5公里的倍数
int extraFactor=extraTotal/5;
//超过的距离对5公里取余
int fraction=extraTotal % 5;
//价格计算
int price=1+extraFactor*1;
return fraction>0?++price:price;}
}//地铁价格计算策略
public  class SubwayStrategy implements CalculateStrategy{// 六公里内3元,6~12公里4元,12~22公里5元,22~32公里6元
// @param km 公里//@return
@Override
public int caculatePrice(int km){
if(km<6) {
return 3;
}else if(km>6 && km<12) {
return 4;
}else if(km>12&&km<22){
return 5;
}
else if(km>22&&km<32){
return 6;
}
//其他距离我们简化为7元钱
return 7;}
}

我们创建一个扮演Context角色的类,这里将它命名为TranficCalculator,具体代码如下

//公交出行价格计算器
public class TranficCalculator{
public static void main(String[] args){
TranficCalculator calculator=new TranficCaculator();
// 设置计算策略
caculator.setStrategy(new BusStrategy()):
//计算价格
System.out.println("公交车乘16公里的价格:"+caculator.caculatePrice(16));
}CalculateStrategy mStrategy;
public void setStrategy(CaculateStrategy mStrategy){
this.mStrategy=mStrategy;
}
public int caculatePrice(int km){
return mStrategy.caculatePrice(km);}
}

分析

这种方案在隐藏实现的同时可扩展性变得更强,例如,当我们需要增加出租车的计算策略时,只需要添加一个出租车计算策略类,然后该策略设置给TranficCalculator,最好直接通过TranficCaculator对象的计算方法即可。

总结

策略模式通过建立抽象,将不同的策略构建成一个具体的策略实现,通过不同的策略实现算法替换。在简化逻辑,结构的同时,增强了系统的可读性,稳定性,可扩展性,这对于较为复杂的业务逻辑显得更为直观,扩展也更为方便。

时势造英雄之策略模式相关推荐

  1. 《Android源码设计模式解析与实战》读书笔记(七)——策略模式

    第六章抽象工厂模式实在是不好理解,我觉得也不能似懂非懂就算了,毕竟这次决定第一遍通读起码要搞懂各种设计模式的基本思想,在源码中如何体现都可以等到阅读代码的能力上去了慢慢消化,但是概念什么的,还是不能就 ...

  2. 【Design pattern】简单工厂过渡策略模式

    把自己当做小菜来跟学<大话设计模式>,跟着故事的思路来走 简单工厂模式:实现一个计算器代码 策略模式:商场打折代码 根据大鸟和小菜的故事,一步步的完善问题的过程!

  3. 设计模式 之美 -- 策略模式

    策略模式作为行为型设计模式中的一种,主要封装相同功能的不同实现算法,用于在用户程序内部灵活切换.对用户来说能够快速替换对应的算法,能够让算法的实现独立于使用的用户. 基本的UML类图如下: 用户使用S ...

  4. 设计模式之策略模式(Strategy)摘录

    23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...

  5. Java中的策略模式实例教程

    策略模式是一种行为模式.用于某一个具体的项目有多个可供选择的算法策略,客户端在其运行时根据不同需求决定使用某一具体算法策略. 策略模式也被称作政策模式.实现过程为,首先定义不同的算法策略,然后客户端把 ...

  6. else 策略模式去掉if_设计模式(三)——简单的状态模式代替if-else

    博主将会针对Java面试题写一组文章,包括J2ee,SQL,主流Web框架,中间件等面试过程中面试官经常问的问题,欢迎大家关注.一起学习,一起成长. 前言 大多数开发人员现在还在使用if else的过 ...

  7. C++模式学习------策略模式

    当遇到同一个对象有不同的行为,方法,为管理这些方法可使用策略模式. 策略模式就是对算法进行包装,是把使用算法的责任和算法本身分割开来.通常把一个系列的算法包装到一系列的策略类里面,这些类继承一个抽象的 ...

  8. 模板方法模式与策略模式的区别

    2019独角兽企业重金招聘Python工程师标准>>> 模板方法模式:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以在不改变算法结构的情况下,重新定义 ...

  9. 【设计模式】 模式PK:策略模式VS状态模式

    1.概述 行为类设计模式中,状态模式和策略模式是亲兄弟,两者非常相似,我们先看看两者的通用类图,把两者放在一起比较一下. 策略模式(左)和状态模式(右)的通用类图. 两个类图非常相似,都是通过Cont ...

最新文章

  1. OutputFormat接口实现类
  2. MySQL buffer pool里的三种链表和三种page
  3. 8s保留cpu设置_使用资源设置控制CPU资源
  4. JavaScript学习(三十四)—事件委托
  5. Python21天打卡Day15-21 函数+参数
  6. acWing 1296 聪明的燕姿
  7. java 反射 接口_Java 怎么通过反射获取并实现这个类里面的接口,并且实现接口中的方法...
  8. 并联串联混合的电压和电流_如何从本质上判断电压表测量谁的电压?
  9. 一年读完100本书(5/100)《创新者的窘境》2021-02-25
  10. 中元节,会吃的民族带你了解“鬼节”的习俗
  11. 手机vnc连接云服务器,云服务器管理终端(VNC连接)说明
  12. H3BPM实例分享——金额规则大写
  13. MySQL工作有多努力--了解MySQL Threads Running
  14. 入门推荐系统,这25篇综述文章足够了
  15. 五大数据统计分析软件
  16. 【前端】Vue+Element UI案例:通用后台管理系统-用户管理:Form表单填写、Dialog对话框弹出
  17. 普惠微光汇聚暖阳,招联携手奋斗者筑梦前行
  18. 达梦8在VMware虚拟机麒麟系统下命令安装
  19. 数据分析:杜邦分析法
  20. Small Talk Matters【闲谈很重要】

热门文章

  1. [数据仓库复习] —— 维度数据模型
  2. 微信公众平台后台数据如何分析
  3. python getcwd_python – 执行os.getcwd()时出错?
  4. DCOS搭建zookeeper集群搭建
  5. ValueError: A 0.7-series setuptools cannot be installed with distribute.
  6. 高通 Camx debug log控制
  7. 如何通过Matplotlib画圆
  8. 微机原理8086CPU结构和功能
  9. MFC 中 如何屏蔽Esc和Ente
  10. 电子邮箱是什么?注册邮箱163、tom、qq等品牌有什么好处?