JAVA设计模式之策略模式 - Strategy

在策略模式(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!
    呱呱叫

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

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

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

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

结语

设计模式源于生活

(0)

相关推荐

  • 设计模式之策略模式

    策略模式 Strategy Intro 策略模式(Strategy):它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化不会影响到使用算法的 Context. 策略模式是一种定 ...

  • 点外卖,让我想起了 策略模式【原创】

    回复"000"获取大量电子书 本篇文章是设计模式系列的第三篇: 模板模式 单例模式 今天给大家分享的是策略模式,具体内容大纲如下: 生活案例 在这互联网时代,尤其是在城市中,有一帮 ...

  • 设计模式:策略模式,Java集合定制排序的核心思想

    前言 前阵子面试的时候,有个面试官问我了解哪些设计模式吗?我说了策略模式.接着他问有哪些场景应用,我又回答他jdk的集合工具类有个排序方法就用到了策略模式,也就是java.util包下的Collect ...

  • 设计模式之策略模式和状态模式(strategy pattern & state pattern)

    本文来讲解一下两个结构比较相似的行为设计模式:策略模式和状态模式.两者单独的理解和学习都是比较直观简单的,但是实际使用的时候却并不好实践,算是易学难用的设计模式吧.这也是把两者放在一起介绍的原因,经过 ...

  • Java设计模式【命令模式】

    命令模式 命令模式很好理解,举个例子,司令员下令让士兵去干件事情,从整个事情的角度来考虑,司令员的作用是,发出口令,口令经过传递,传到了士兵耳朵里,士兵去执行.这个过程好在,三者相互解耦,任何一方都不 ...

  • PHP设计模式之策略模式

    PHP设计模式之策略模式 策略模式,又称为政策模式,属于行为型的设计模式. Gof类图及解释 GoF定义:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换.本模式使得算法可独立于使用它的 ...

  • [PHP小课堂]PHP设计模式之策略模式

    [PHP小课堂]PHP设计模式之策略模式 关注公众号:[硬核项目经理]获取最新文章 添加微信/QQ好友:[DarkMatterZyCoder/149844827]免费得PHP.项目管理学习资料

  • 设计模式(22) 策略模式

    在策略模式中,一个类的行为或算法可以在运行时动态更改. GOF对策略模式的描述为: Define a family of algorithms, encapsulate each one, and m ...

  • 图解Java设计模式之解释器模式

    图解Java设计模式之解释器模式 四则运算问题 传统方案解决四则运算问题分析 解释器模式基本介绍 解释器模式来实现四则 解析器模式在Spring框架中的源码分析 解释器模式的注意事项和细节 四则运算问 ...

  • 图解Java设计模式之备忘录模式

    游戏角色状态恢复问题 传统方案解决游戏角色恢复 传统的方式的问题分析 备忘录模式基本介绍 备忘录模式原理类图 游戏角色恢复状态实例 备忘录模式的注意事项和细节 游戏角色状态恢复问题 游戏角色有攻击力和 ...