在策略模式(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. 「SDFZ听课笔记」二分图&&网络流

    二分图? 不存在奇环(长度为奇数的环)的图 节点能黑白染色,使得不存在同色图相连的图 这两个定义是等价哒. 直观而言,就是这样的图: 二分图有一些神奇的性质,让一些在一般图上复杂度飞天的问题可以在正常 ...

  2. python3 分布式进程(跨机器)BaseManager(multiprocessing.managers)

    A机器负责发送任务和接受结果: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 #ta ...

  3. 算法实现c语言--02

    从键盘上输入字符,将小写字母转换成大写字母.输入“ctl + z” 结束 . #include<stdio.h> #include<stdlib.h> //从键盘上输入字符,将 ...

  4. bzoj2959

    lct+并查集 联赛之后忘了很多东西 复习一下 这并不是一棵树,所以我们不能直接上lct 但是把双联通分量缩了以后就是一棵树了 怎么缩呢 就是把splay拆了合并到一个点上 连通性和双联通分量拿两个并 ...

  5. python 数据可视化

    一.基本用法 import numpy as np import matplotlib.pyplot as plt x = np.linspace(-1,1,50) # 生成-1到1 ,平分50个点 ...

  6. 带emoji表情弹出层的评论框,semantic+emoji picker,java.sql.SQLException: Incorrect string value: '\xF0\x9F..'

    在自己做一个项目玩时,在做评论的时候. 选中了semantic.js原型,这个在国内用的不是很多,但是在github上star数量很高,想当初我想找一个js框架是就在上面找的. semantic中文网 ...

  7. JavaScript代码风格和分号使用问题

    1.推荐代码风格 JavaScript Standard Style  规定相对松散更多人使用此规范 Airbnb JavaScript Style  规定更严格但也没毛病 2.JavaScript代 ...

  8. 51nod 1068【简单博弈】

    思路 手动打表, N 1 : A出1 A胜: 2 : A出2 A胜: 3 : A只能出2的整数幂&&这个数<=3,所以只能出1,2:A出1的时候,B就是2的情况,B胜:A出2的时 ...

  9. HDU5119【dp背包求方案数】

    题意: 有n个数,问有多少方案满足取几个数的异或值>=m; 思路: 背包思想,每次就是取或不取,然后输出>=m的方案就好了. #include <bits/stdc++.h> ...

  10. 51nod1093(推公式&找規律)

    題目鏈接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1093 題意:中文題誒- 思路:xjb 一開始死活想不出怎麼將一 ...