在策略模式(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. codevs 3269 混合背包(复习混合背包)

    传送门 [题目大意]给出物品的数量.-1为无限个. [思路]混合背包.... [code] #include<iostream> #include<cstdio> #inclu ...

  2. bzoj 4668 冷战——并查集结构

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4668 不路径压缩,维护并查集的树的结构,查询链上最大值.按秩合并就可以暴爬. #includ ...

  3. poj1151 Atlantis——扫描线+线段树

    题目:http://poj.org/problem?id=1151 经典的扫描线问题: 可以用线段树的每个点代表横向被矩形上下边分割开的每一格,这样将一个矩形的出现或消失化为线段树上的单点修改: 每个 ...

  4. PTA 哈希查找 除留取余法

    PTA 电话聊天狂人(25 分) 给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人. 输入格式: 输入首先给出正整数N(≤10​5​​),为通话记录条数.随后N行,每行给出一条通话记录.简单起 ...

  5. CS231n 2016 通关 第五、六章 Batch Normalization 作业

    BN层在实际中应用广泛. 上一次总结了使得训练变得简单的方法,比如SGD+momentum RMSProp Adam,BN是另外的方法. cell 1 依旧是初始化设置 cell 2 读取cifar- ...

  6. Identity Server 4 原理和实战(完结)_为 MVC 客户端刷新 Token

    服务端修改token的过期使劲为60秒 过期了 仍然还能获取到api1的资源 api1,设置每隔一分钟就验证token 并且要求token必须要有超时时间这个参数, 1分钟后提示超时,两边都是一分钟, ...

  7. 关于weblogic 10.3.6.0 的漏洞复现(2)

    今天小R又学会了一个工具的使用,而且这个工具很强大很强大. 待会介绍. 一.需要的试验环境: 一台宿主机,虚拟机(kali+window2008或其他版本的windows)  1.宿主机需要的工具:B ...

  8. Spring Boot2中配置HTTPS

    1.生成证书 使用jdk,jre中的keytool.exe生成自签名的证书,需要配置JAVA_HOME和path环境变量,即jdk的环境变量.命令如下: keytool -genkey -alias ...

  9. Docker 网络模型之 macvlan 详解,图解,实验完整

    本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫. 上一篇文章我们 ...

  10. 51nod1459【二级最短路】

    标签说的是BFS... 太菜,不知道怎么BFS...是不是spfa写,就叫BFS...感觉不是.... 只是二级最短路的写法,直接搞就很容易了,简单题: #include <bits/stdc+ ...