详解Java策略模式

一、策略模式到底是什么?

策略模式属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。

简单的说,策略模式代表了一类算法的通用解决方案,你可以在运行时选择使用哪种解决方案。

策略模式的重心

策略模式的重心不是如何实现算法, 而是如何组织、调用这些算法, 从而使得程序结构更加灵活,具有更好的维护性和扩展性。

算法的平等性

策略模式一个很大的特点就是各个策略算法的平等性。对于一系列具体的策略算法,地位都是一样的,因此可以实现算法之间可以互相替换。所有的策略算法在实现上也是相互独立的,相互之间是没有依赖的。所以可以这样描述这一系列策略算法:策略算法是相同行为的不同实现。

运行时策略的唯一性

运行期间,策略模式在每一个时刻只能使用一个具体的策略实现对象,虽然可以动态地在不同的策略实现中切换,但是同时只能使用一个。

公有的行为

经常见到的是,所有的具体策略都有一些公有的行为。这时候,就应该把这些公有的行为放到共同的抽象策略角色

Strategy类里面。这时不能使用接口,应该使用抽象类来实现。

二、策略模式的结构

策略模式包含三部分内容:(如下图所示)

  • a.一个或多个使用策略对象的客户.(环境角色)
  • b.一个代表某个算法的接口, 它是策略模式的接口. (抽象策略角色)
  • c.一个或多个该接口的具体实现, 它们代表了算法的多种实现.(具体策略角色)

三、策略模式的应用

  • a.容错恢复机制, 程序运行的时候, 如果发生某种错误, 系统并不会直接挂掉或者说影响系统的其他功能点.
  • 而是系统可以容忍这样的错误, 并且事先提供好了这种容错恢复机制, 来使得程序正常的运行下去.
  • 例如: 一个系统要对所有的操作进行日志记录, 且需要把日志记录落库, 方便后续的使用, 但是在把日志记录落库的时候,
  • 可能会发生错误, 如数据库出现问题, 那就先可以记录在文件里面, 等到数据库问题修复, 再把文件中的日志记录同步到数据库中去
  • 对于这样的功能设计, 可以采用策略设计模式, 根据需要在运行期间进行动态的切换.
  • b.假设现在要设计一个会员机制的购物系统, 对本系统的所有SVIP提供打八折的购物优惠,
  • 对本系统的所有VIP提供打九折的购物优惠, 对非会员购物不打折. 那么对于这样的系统功能设计, 也可以采用策略模式来设计.
  • c.使用不同的条件(物品的重量或者颜色等)来筛选库存中的物品, 可以将这一模式应用到更广泛的领域,
  • 比如使用不同的标准来验证输入的有效性, 使用不同的方式来分析或者格式化输入.

四、策略模式Demo

假设现在需要根据业务的需求,对调用接口传进来的参数,选择合适的策略进行处理,这里假设有策略一和策略二。

Client:

/**
 * @author lyh
 * @version v-1.0.0
 * @since 2021/6/2
 */
public class Client {
    public static void main(String[] args) {
        //根据需要客户自行选择策略
        //加入Java开发交流君样:756584822一起吹水聊天
        //选择策略1
        StrategyObj strategyOne = new StrategyObj(new StrategyOne());
        System.out.println(strategyOne.strategy("one"));
        //选择策略2
        StrategyObj strategyTwo = new StrategyObj(new StrategyTwo());
        System.out.println(strategyTwo.strategy("two"));
    }
}

输出:
执行策略1!
执行策略2!

Process finished with exit code 0

策略接口:

/**
 * @desc:策略接口
 */
public interface Strategy {
    String execute(String s);
}

/**
 * @desc:策略接口封装
 */
public class StrategyObj {

    private final Strategy strategy;

    public StrategyObj(Strategy v) {
        this.strategy = v;
    }

    public String strategy(String s) {
        return strategy.execute(s);
    }//加入Java开发交流君样:756584822一起吹水聊天

}

策略实现:

/**
 * @desc:策略一
 */
public class StrategyOne implements Strategy {
    @Override
    public String execute(String s) {
        return "执行策略1!";
    }
}

/**
 * @desc:策略二
 */
public class StrategyTwo implements Strategy {
    @Override
    public String execute(String s) {
        return "执行策略2!";
    }
}

五、使用Lambda表达式

通过上面的demo应该可以意识到Strategy是一个函数式接口;除此之外,它还与Predicate<String>具有同样的函数描述。这意味着我们不需要声明新的类来实现不同的策略,通过直接传递Lambda表达式就能达到同样的目的且更简洁。

public class Client {
    public static void main(String[] args) {
        StrategyObj strategyOne = new StrategyObj((String s) -> {return "执行策略1";});
        System.out.println(strategyOne.strategy("one"));
         //加入Java开发交流君样:756584822一起吹水聊天
        StrategyObj strategyTwo = new StrategyObj((String s) -> {return "执行策略2";});
        System.out.println(strategyTwo.strategy("two"));
    }
}

Lambda表达式避免了采用策略设计模板时僵化的模板代码。仔细看上面的代码会发现,Lambda表达式实际已经对策略进行了封装, 这就是创建策略设计模式的初衷.

六、策略模式的优缺点

优点

  • a.使用策略模式可以避免使用多重条件if…else if…else语句, 多重条件不易维护且代码可读性差.
  • b.策略模式提供了管理相关的算法族的办法. 策略类的等级结构定义了一个算法或者行为族. 恰当使用继承可以把公共的代码移到父类里面, 从而避免代码重复

缺点

  • a.客户端必须知道所有的策略类, 并自行决定使用哪一个策略类. 这就意味着客户端必须理解这些算法的区别, 以便适时选择恰当的算法类. 换言之, 策略模式只适用于客户端知道算法或行为的情况.
  • b.由于策略模式把每个具体的策略实现都单独封装成类, 如果备选的策略很多的话, 那么对象的数目就会很多.

到此这篇关于详解Java策略模式的文章就介绍到这了,更多相关Java策略模式内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • java设计模式学习之策略模式

    策略模式:策略模式是一种定义一系列算法的方法,算法完成的工作都是相同的工作,但是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合. Java实现一个策略模式: 需求:商场收银系统,收银方式为正常收费,打八折,满300返100,这三种收费方式. 1:创建一个超类.即收费的抽象方法. public abstract class CashSuper { public abstract double acceptCash(double money); } 2:创建实现此

  • 详解Java编程中的策略模式

    策略模式属于对象的行为模式.其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换.策略模式使得算法可以在不影响到客户端的情况下发生变化. 策略模式的结构 策略模式是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理.策略模式通常把一个系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类.用一句话来说,就是:"准备一组算法,并将每一个算法封装起来,使得它们可以互换".下面就以一个示意性的实现讲解策略模式实例的结构. 这个

  • Java通俗易懂系列设计模式之策略模式

    介绍 策略设计模式是行为设计模式之一.当我们为特定任务使用多个算法时,使用策略模式,客户端决定在运行时使用的实际实现. 策略模式的最佳示例之一是Collections.sort()采用Comparator参数的方法.基于Comparator接口的不同实现,对象将以不同的方式进行排序. 实例 对于我们的示例,我们将尝试实施一个简单的购物车,我们有两种付款策略 - 使用信用卡或使用PayPal. 首先,我们将为我们的策略模式示例创建接口,在我们的例子中,支付金额作为参数传递. 支付方式:Paymen

  • Java使用策略模式解决商场促销商品问题示例

    本文实例讲述了Java使用策略模式解决商场促销商品问题.分享给大家供大家参考,具体如下: 一 模式定义 策略模式:定义一系列的算法,将每一种算法封装起来并可以相互替换使用,策略模式让算法独立于使用它的客户应用而独立变化. 二 模式举例 1 模式分析 我们借用商场促销商品来说明这一模式. 2 策略模式静态类图 3 代码示例 3.1 创建策略接口一IStrategy package com.demo.strategy; /** * 策略接口 * * @author * */ public inter

  • 对比Java设计模式编程中的状态模式和策略模式

    为了能在Java应用程序中正确的使用状态模式和策略模式,开发人员需要清楚地知道这两种模式之间的区别.尽管状态模式和策略模式的结构非常相似,它们又同样遵循开闭原则,都代表着SOLID设计原则的'O',但它们的意图是完全不同的.Java中的策略模式是对一组相关的算法进行封装,给调用方提供了运行时的灵活性.调用方可以在运行时选择不同的算法,而不用修改使用策略的那个Context类.使用策略模式的经典例子包括实现加密算法,压缩算法,以及排序算法.另一方面,状态模式使用一个对象可以在不同的状态下表现出不同

  • 详解Java策略模式

    一.策略模式到底是什么? 策略模式属于对象的行为模式.其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换.策略模式使得算法可以在不影响到客户端的情况下发生变化. 简单的说,策略模式代表了一类算法的通用解决方案,你可以在运行时选择使用哪种解决方案. 策略模式的重心 策略模式的重心不是如何实现算法, 而是如何组织.调用这些算法, 从而使得程序结构更加灵活,具有更好的维护性和扩展性. 算法的平等性 策略模式一个很大的特点就是各个策略算法的平等性.对于一系列具体的

  • 详解JAVA 原型模式

    原型模式 原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆.当直接创建对象的代价比较大时,则采用这种模式.例如,一个对象需要在一个高代价的数据库操作之后被创建.我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用. 介绍 意图: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.

  • 详解java迭代器模式

    场景 提供一种可以遍历聚合对象的方式.又称为:游标cursor模式 聚合对象:存储数据 迭代器:遍历数据 JDK内置的迭代器(List/Set) package com.qianyu.gof.iterator; import java.util.ArrayList; import java.util.Iterator; /** * @author lijing * @date 2019-04-10-14:38 * @discroption JDK内置迭代器测试类 */ public class

  • Java 策略模式 if-else用法实例详解

    目录 引言: 策略模式 comparable接口 comparator接口 不同的排序策略实现 策略模式比if-else香在哪呢?有缺点吗? 策略模式有哪些使用场景呢? 有N多个策略怎么办? 总结 引言: 公司要扩大规模,目前需要购买一批汽车,还要招聘一批保安,老板指示暂时只想看新车,只需要给他看按照价格排好序的新车列表就行:保安候选人按照安保工作经验排好序给他一个列表. 汽车数据,还有保安候选人的数据已经放在了程序员的面前,你只需要给我个列表就好了. 基于这个需求,我们自然而然的会想到排序啊.

  • 详解Java设计模式之桥接模式

    目录 一.什么是桥接模式: 二.UML结构图 三.代码实现 四.JDBC源码解析-桥接模式 1.源码分析 2.源码类 3.对 JDBC 的观点 一.什么是桥接模式: 桥接,顾名思义,就是用来连接两个部分,使得两个部分可以互相通讯,桥接模式的作用就是为被分离的抽象部分和实现部分搭桥.在现实生活中一个物品在搭配不同的配件时会产生不同的动作和结果,例如一辆赛车搭配的是硬胎或者是软胎就能够在干燥的马路上行驶,而如果要在下雨的路面行驶,就需要搭配雨胎了,这种根据行驶的路面不同,需要搭配不同的轮胎的变化的情

  • Java设计模式详解之门面模式(外观模式)

    门面模式(Facade Pattern)也叫外观模式,它隐藏系统的复杂性,并向客户端提供一个可以访问系统的接口.这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性,为子系统中的一组接口提供了一个统一的高层访问接口,这个接口使得子系统更容易被访问或使用.这种模式涉及到一个单一的类,该类提供了客户端请求的简化方法和对现有系统类方法的委托调用. 简而言之,就是把一堆复杂的流程封装成一个接口供给用户更简单的使用,这个设计模式里有三个角色: 1)门面角色( facade ):

  • 详解JAVA设计模式之代理模式

    什么是设计模式(Design Pattern)? 设计模式是一套被反复使用,多数人知晓的,经过分类编目的,代码设计经验的总结. 代理模式的定义? 代理模式就是为其他对象提供一种代理,以控制对这个对象的访问. 代理对象起到中介作用,可去掉功能服务或增加额外的服务. 代理对象和目标对象的关系? 代理对象:增强后的对象 目标对象:被增强的对象 他们不是绝对的,会根据情况发生变化. 代理模式的两种实现方式? 1.静态代理:代理和被代理对象在代理之前是确定的,它们都实现相同的接口或者继承相同的抽象类. 2

  • 详解JAVA设计模式之模板模式

    在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板.它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行.这种类型的设计模式属于行为型模式. 介绍 意图:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 主要解决:一些方法通用,却在每一个子类都重新写了这一方法. 何时使用:有一些通用的方法. 如何解决:将这些通用算法抽象出来. 关键代码:在抽象类实现,其他步骤在子

  • 详解JAVA 设计模式之状态模式

    在状态模式(State Pattern)中,类的行为是基于它的状态改变的.这种类型的设计模式属于行为型模式. 在状态模式中,我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象. 介绍 意图: 允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类. 主要解决: 对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为. 何时使用: 代码中包含大量与对象状态有关的条件语句. 如何解决: 将各种具体的状态类抽象出来. 关键代码: 通常

  • 详解Java从工厂方法模式到 IOC/DI思想

    前言 简单工厂的本质是选择实现,说白了是由一个专门的类去负责生产我们所需要的对象,从而将对象的创建从代码中剥离出来,实现松耦合.我们来看一个例子: 我们要创建一个文件导出工具 public interface FileOper{ public Boolean exceptFile(String data); } public class XMLFileOp implment FileOper{ public Boolean exceptFile(String data){ System.out.

随机推荐