在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。

在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。

介绍

什么是策略模式(Strategy Pattern)

在软件开发过程中常常遇到这样的情况, 实现某一个功能有很多种算法或实现策略, 我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能. 如果将这些算法或者策略抽象出来, 提供一个统一的接口, 不同的算法或者策略有不同的实现类, 这样在程序客户端就可以通过注入不同的实现对象来实现算法或者策略的动态替换, 这种模式的可扩展性和可维护性也更高, 这就是策略模式.

策略模式的定义(Strategy Pattern)

策略模式: 定义了算法族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立与使用算法的客户.(摘抄于Head First设计模式)

简单理解: 定义了一系列算法,每个算法封装起来,各个算法之间可以互相替换,且算法的变化不会影响到使用算法的客户,属于行为型模式.

使用场景

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

例如:

或出现大量 if-else 判断时可以使用策略模式优化代码.

例如电商网站支付方式,一般分为银联,微信,支付宝,可以采用策略模式,每一种方式作为一种支付方式的实现,如果哪一个支付方式发生变化,只需要修改对应的实现即可,不需要修改调用的客户端,如果引入新的支付方式,如:随行付,则只需要增加一个对应的随行付实现类即可,遵循开闭原则.

组成部分(三个角色)

1. 抽象策略(Strategy):

通常由接口或抽象类实现. 定义了多个具体策略的公共接口, 具体策略中各种不同的算法以不同的方式实现这个接口; Context使用这些接口调用不同实现的算法.

2. 具体策略(ConcreteStrategy):

实现了Strategy接口或继承与抽象类, 封装了具体的算法和行为.

3. 环境类(Context):

持有一个公共策略接口的引用(Strategy), 直接给客户端调用.

优缺点及重点

优点:

  • 每个算法单独封装, 减少算法与算法调用者之间的耦合;
  • 算法可以自由切换;
  • 避免使用多重条件判断;
  • 扩展性良好;

缺点:

  • 策略类会增多.
  • 所有策略类都需要对外暴露.

重点

  • 给对象传入什么样的策略, 就执行什么样的动作.

实现

类图

说明: 代码来自Head First设计模式中SimUDuck的示例.

代码结构:

抽象策略(Strategy):

/**
* 飞行行为
*/
public interface FlyBehavior {
//各种飞行实现
public void fly(); }

具体策略(ConcreteStrategy):

public class FlyWithWings implements FlyBehavior {
@Override
public void fly() {
System.out.println("I'm flying!");
}
}

环境类(Context):

/**
* 鸭子类
*/
public abstract class Duck { //持有一个公共策略接口的引用
public FlyBehavior flyBehavior;
public QuackBehavior quackBehavior; public void swim() {
System.out.println("我会游泳...");
} public abstract void display(); public void performFly() {
flyBehavior.fly();
} public void performQuack() {
quackBehavior.quack();
} //提供set方法, 使鸭子可以动态改变飞行策略
public void setFlyBehavior(FlyBehavior flyBehavior) {
this.flyBehavior = flyBehavior;
} //提供set方法, 使鸭子可以动态改变叫声策略
public void setQuackBehavior(QuackBehavior quackBehavior) {
this.quackBehavior = quackBehavior;
}
}
/**
* 绿头鸭
*/
public class MallardDuck extends Duck { @Override
public void display() {
System.out.println("绿头鸭");
} public MallardDuck() {
/*MallardDuck 继承 Duck, 所以具有quackBehavior 和 flyBehavior实例变量
当MallardDuck实例化时, 它的构造器会把继承的quackBehavior,
flyBehavior实例变量初始化成Quack,FlyWithWings类型的新实例
*/
quackBehavior = new Quack();
flyBehavior = new FlyWithWings();
}
}

测试类:

public static void main(String[] args) {
Duck mallard = new MallardDuck();
//飞行
mallard.performFly();
//改变鸭子行为(传入飞行策略)
mallard.setFlyBehavior(new FlyRocketPowered());
mallard.performFly();
//叫声
mallard.performQuack();
} 执行结果:
I'm flying!
I'm flying with a rocket!
呱呱叫

生活中的策略模式(我的猜想)

俗话说: 人是铁饭是钢, 一顿不吃饿的慌;吃饭也有策略模式, 你晓得嘛.

人(环境类)饿了要吃饭(抽象策略), 但是吃什么你知道吗? 这时你的大脑就会调集你的毕生功力(经验, 生活经历, 常识等等),来知道有哪些东西是可以吃的,比如鸡腿,面包或粥等等(具体策略,暴露所有策略).大脑选择(动态选择策略)吃其中的一种或多种食物来应对身体的不满.

生活中这样的例子还有很多,网上购物(不同的商品即: 具体策略), 世界那么大, 我想去转转.(转转的方式即: 具体策略)等.

结语

设计模式源于生活

JAVA设计模式之策略模式 - Strategy的更多相关文章

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

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

  2. Java设计模式之策略模式(Strategy)

    前言: 最近一直在学习基于okHttp网络请求,学习的过程中就想起了之前项目中有这么一个需求不同的接口要采用不同的加密方式,比如登录之前要采用RSA加密,登录之后要采用AES加密,当时是采用靠传递一个 ...

  3. 反馈法学习设计模式(一)——策略模式Strategy Pattern

    简介(Introduction) 之前学习Java8实战时,遇到一个很好的策略模式示例.便想着借着这个示例结合反馈式的方法来,学习策略设计模式,也以便后面反复琢磨学习. 首先我们通过练习,逐步写出符合 ...

  4. 8.6 GOF设计模式四: 策略模式… Strategy Pattern

    策略模式… Strategy Pattern  在POS系统中,有时需要实行价格优惠, 该如何处理?  对普通客户或新客户报全价  对老客户统一折扣5%  对大客户统一折扣10%  注:课件 ...

  5. 二十四种设计模式:策略模式(Strategy Pattern)

    策略模式(Strategy Pattern) 介绍定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换.本模式使得算法的变化可独立于使用它的客户. 示例有一个Message实体类,对它的操作有 ...

  6. Java设计模式1——策略模式(Strategy Pattern)

    最近觅得一本好书<您的设计模式>,读完两章后就能断言,一定是一头极品屌丝写的,而且是专写给开发屌丝男的智慧枕边书,小女子就委屈一下,勉强看看,人笨,谁让他写得这么通俗易懂呢!为了加深理解, ...

  7. JAVA设计模式一策略模式(Strategy Pattern)

    什么是设计模式? 就是一些经验.让程序代码更具弹性.好维护.代码复用的经验.而且设计模式都遵从一些OO设计原则. 题外话:以下罗列出常用的OO设计原则:链接 本文章介绍策略模式(Strategy Pa ...

  8. Java设计模式之策略模式(Strategy Pattern)

    简介 策略模式定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户. 组成 1.抽象策略角色(Strategy): 策略类,通常由一个接口或者抽象类实现. 2.具 ...

  9. 折腾Java设计模式之策略模式

    博客原文地址 简介 在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改.这种类型的设计模式属于行为型模式.简单理解就是一组算法,可以互换,再简单点策略就是封装算法. ...

随机推荐

  1. hdu-5358 First One(尺取法)

    题目链接: First One Time Limit: 4000/2000 MS (Java/Others)     Memory Limit: 131072/131072 K (Java/Other ...

  2. python中format()方法格式化字符串

    format()是python2.6新增的一个格式化字符串的方法,功能非常强大,有可能在未来完全替代%格式化方法,相比 % ,format()的优点有: 1 .格式化时不用关心数据类型的问题,form ...

  3. 【整理】XOR:从陌生到头晕

    一:解决XOR常用的方法: 在vjudge上面输入关键词xor,然后按照顺序刷了一些题. 然后大概悟出了一些的的套路: 常用的有贪心,主要是利用二进制的一些性质,即贪心最大值的尽量高位取1. 然后有前 ...

  4. SSH框架中hibernate 出现 user is not mapped 问题

    SSH框架中hibernate 出现 user is not mapped 问题      在做SSH框架整合时,在进行DAO操作时.这里就只调用了chekUser()方法.运行时报  user is ...

  5. 三、mysql登录详解及版本号查询

    1.用window+r,输入cmd,用mysql -uuser -ppassword登录时出现‘mysql’不是有效的内部命令? 答:这是因为没有配置MySQL的环境变量path所致. MySQL的环 ...

  6. [转]Eclipse创建Maven项目

    构建Maven项目的完整过程--普通web项目(Eclipse) 进行以下步骤的前提是你已经安装好本地maven库和eclipse中的maven插件了(有的eclipse中已经集成了maven插件) ...

  7. git搭建私有仓库

    git gui参考 https://ask.helplib.com/git/post_1004941

  8. E20180605-hm

    arbitrary adj. 乱; 随意的,任性的,随心所欲的; 主观的,武断的; 霸道的,专制的,专横的,独断独行的; session n. 开会,会议; (法庭的) 开庭; 会期,学期; (进行某 ...

  9. 3DMAX 烘培技术

    烘培是指,把光照信息渲染成贴图,而后把这个烘培后的贴图再贴回到场景中去的技术.烘培技术把光照计算的结果提前写入到了贴图中,因此在实时渲染中不需要进行耗时的光照计算,大大提高了实时渲染的效率. 烘培和渲 ...

  10. c# IOCP.ClientEx2.ReadWrite 加断点遭遇System.AccessViolationException 问题

    起因: 如果在Debug模式下,在IOCP.ClientEx2.ReadWrite.cs while (0 > (nPackSize = _ipcp.Pack(arg_n64PackId, ar ...