Java设计模式-策略模式

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

什么是策略模式?

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

理论有些抽象,举个简单的例子各位就容易理解了...

我们去上课、上班、出差、旅游,需要选择合适的出行方式,是选择步行?公交?火车?还是飞机?...

这种选择其实就是一种“策略”。当然,针对这个例子,一种出行方式可能满足不了我们的需求,我们可能需要搭配不同的出行方式出行,这种多重选择其实也是一种“策略”。

编码实战

需求是这样的:某商场想要开展3种销售模式,而且可以相互之间任意选择转换... 第1种销售模式:正常销售 第2种销售模式:打折销售(如:全场商品9折、全场8折...) 第3种销售模式:返现销售(如:全场商品满500元返现100元)

直白点分析,其实就是让我们对用户购买商品的总金额进行“模式处理”,得到最终付款金额。 话不多说,开始上代码...

  1. 搭建抽象策略角色
/**
 * 价格策略接口(所有价格策略的父类)
 * Created by Wangnan on 2016/8/19.
 */
public interface PriceStrategyInterface {
    /**
     * 获取执行策略后得到的金额
     */
    float getStrategyResult();
}
  1. 构建具体策略角色(正常价格策略,打折价格策略,返现价格策略)
/**
 * @ClassName: NormalPriceStrategy
 * @Description: 正常价格策略
 * @Author Wangnan
 * @Date 2016/8/19
 */
public class NormalPriceStrategy implements PriceStrategyInterface{
    private float mPrice; // 用户购物总价
    public NormalPriceStrategy(float totalPrice){
        mPrice = totalPrice;
    }
    @Override
    public float getStrategyResult() {
        return mPrice;
    }
}
/**
 * @ClassName: DiscountPriceStrategy
 * @Description: 打折价格策略
 * @Author Wangnan
 * @Date 2016/8/19
 */
public class DiscountPriceStrategy implements PriceStrategyInterface{
    private float mPrice; // 用户购物总价
    private float mDiscountRate; // 折扣率(0F ~ 1F)
    public DiscountPriceStrategy(float price , float discount){
        mPrice = price;
        if(discount >= 0F && discount <= 1F) { //折扣率越界判断
            mDiscountRate = discount;
        }else{
            mDiscountRate = 1;
        }
    }
    @Override
    public float getStrategyResult() {
        return mPrice * mDiscountRate;
    }
}
/**
 * @ClassName: ReturnPriceStrategy
 * @Description: 返现价格策略
 * @Author Wangnan
 * @Date 2016/8/19
 */
public class ReturnPriceStrategy implements PriceStrategyInterface{
    private float mPrice; // 用户购买总价
    private float mReturnPriceStandard; // 返现标准
    private float mReturnPrice; // (满足返现标准) 返现金额
    public ReturnPriceStrategy(float price, float returnPriceStandard, float returnPrice){
        mPrice = price;
        mReturnPriceStandard = returnPriceStandard;
        mReturnPrice = returnPrice;
    }
    @Override
    public float getStrategyResult() {
        if(mPrice > mReturnPriceStandard){
            return mPrice - (( mPrice / mReturnPriceStandard) * mReturnPrice); // 返现叠加:(举例)满300减100,满600减200,...依次类推
        }else {
            return mPrice;
        }
    }
}
  1. 构造环境角色。【环境角色:持有一个策略类的引用,最终给客户端调用。其实就是策略的调度者(或者说是执行者)】
/**
 * @ClassName: PriceContext
 * @Description: 价格环境角色
 * @Author Wangnan
 * @Date 2016/8/19
 */
public class PriceContext {
    private PriceStrategyInterface mPriceStrategyInterface; // 价格策略接口
    public PriceContext(PriceStrategyInterface priceStrategyInterface){
        mPriceStrategyInterface = priceStrategyInterface;
    }
    /**
     * 执行价格策略 -> 调度策略对象,获取最终价格
     */
    public float executePriceStrategy(){
        return mPriceStrategyInterface.getStrategyResult();
    }
}
  1. 策略模式构造完毕,开始使用(这里给出了3种策略的使用方式)。
// 假设用户购买1000元商品,商场没有购物活动
    float mPrice = 1000F;
    PriceContext context = new PriceContext(new NormalPriceStrategy(mPrice)); // 走正常价格策略
    float finalPrice = context.executePriceStrategy(); // 执行策略,finalPrice = 1000.0
    // 假设用户购买1000元商品,商场进行全场商品打9折活动
    float mPrice2 = 1000F;
    float discountRate = 0.9F;
    PriceContext context2 = new PriceContext(new DiscountPriceStrategy(mPrice2, discountRate)); // 走打折价格策略
    float finalPrice2 = context2.executePriceStrategy(); // 执行策略,finalPrice2 = 900.0
    // 假设用户购买1000元商品,商场进行全场商品满500减100返现活动
    float mPrice3 = 1000F;
    float returnPriceStandard = 500F; // 返现标准
    float returnPrice = 100F; // (满足返现标准)返现金额
    PriceContext context3 = new PriceContext(new ReturnPriceStrategy(mPrice3, returnPriceStandard, returnPrice)); // 走返现价格策略
    float finalPrice3 = context3.executePriceStrategy(); // 执行策略,finalPrice3 = 800.0

至此,我们的“策略模式”就结束了,看完的朋友是不是觉得有点小题大做,把简单的问题给复杂化了呢,针对这个问题确实是!但是,如果你的需求更加多样,更加复杂...你会发现这种设计模式其实可以把你的复杂问题简单化、流程化。

总结

策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化,使算法自身更具灵活性。 拓展

组合两种设计模式

我们常常听说或正在使用的MVC、MVP、MVVM...等模式,其实在很大程度上是将设计模式进行组合规整后形成的...我们今天也要组合一个新模式 - 简单策略工厂模式(将调度的策略进一步用简单工厂模式进行封装,让工厂去生产我们需要的策略)。

  1. 开始改造价格环境角色,封装价格策略工厂
/**
 * @ClassName: PriceContext
 * @Description: 价格环境角色
 * @Author Wangnan
 * @Date 2016/8/19
 */
public class PriceContext {
    private PriceStrategyInterface mPriceStrategyInterface; // 价格策略接口
    public static final int TYPE_NORMAL_PRICE = 0x0001; // 正常价格策略标识符
    public static final int TYPE_DISCOUNT_PRICE = 0x0002; // 折扣价格策略标识符
    public static final int TYPE_RETURN_PRICE = 0x0003; // 返现价格策略标识符
    /**
     *
     * 创建环境角色
     * @param type TYPE_NORMAL_PRICE(正常价格策略),TYPE_DISCOUNT_PRICE(折扣价格策略) or TYPE_RETURN_PRICE(返现价格策略)
     * @param args type = TYPE_NORMAL_PRICE时,只需传入购物总价(args[0])。
     *             type = TYPE_DISCOUNT_PRICE时, 需要传入购物总价(args[0])和折扣率(args[1])
     *             type = TYPE_RETURN_PRICE时,需要传入购物总价(args[0])、返现价格标准(args[1])和返现价格(args[2])
     */
    public PriceContext(int type, float...args){
        switch (type){
            case TYPE_NORMAL_PRICE:
                mPriceStrategyInterface = new NormalPriceStrategy(args[0]); // 创建正常价格策略
                break;
            case TYPE_DISCOUNT_PRICE:
                mPriceStrategyInterface = new DiscountPriceStrategy(args[0], args[1]); // 创建折扣价格策略
                break;
            case TYPE_RETURN_PRICE:
                mPriceStrategyInterface = new ReturnPriceStrategy(args[0], args[1], args[2]); // 创建返现价格策略
                break;
            default:
                mPriceStrategyInterface = new NormalPriceStrategy(args[0]);
                break;
        }
    }
    /**
     * 调度策略对象,执行策略 -> 获取最终价格
     */
    public float executePriceStrategy(){
        return mPriceStrategyInterface.getStrategyResult();
    }
}
  1. 使用价格环境角色(举例)
// 假设用户消费1000元,商品开展全场商品打8.8折活动
    PriceContext mPriceContext = new PriceContext(PriceContext.TYPE_DISCOUNT_PRICE, 1000, 0.88F);
    float finalPrice = mPriceContext.executePriceStrategy(); // finalPrice = 880.0



相关文章
|
5天前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
23 2
|
17天前
|
设计模式 Java 程序员
[Java]23种设计模式
本文介绍了设计模式的概念及其七大原则,强调了设计模式在提高代码重用性、可读性、可扩展性和可靠性方面的作用。文章还简要概述了23种设计模式,并提供了进一步学习的资源链接。
33 0
[Java]23种设计模式
|
1天前
|
设计模式 JavaScript Java
Java设计模式:建造者模式详解
建造者模式是一种创建型设计模式,通过将复杂对象的构建过程与表示分离,使得相同的构建过程可以创建不同的表示。本文详细介绍了建造者模式的原理、背景、应用场景及实际Demo,帮助读者更好地理解和应用这一模式。
|
26天前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
本教程详细讲解Kotlin语法,适合深入学习。快速入门可参考“简洁”系列教程。本文通过游泳运动员的案例,介绍策略模式及其在Kotlin中的改良应用,利用高阶函数简化代码结构,提高灵活性。
27 3
|
27天前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
本教程详细讲解Kotlin语法,适合深入学习。快速入门可参考“简洁”系列教程。本文介绍策略模式在Kotlin中的应用,通过游泳运动员的例子,展示如何使用接口和高阶函数实现策略模式,使代码更简洁、灵活。
27 2
|
28天前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
59 3
|
29天前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
27 3
|
29天前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入解析与实践
【10月更文挑战第9天】 策略模式是一种行为设计模式,它允许在运行时选择算法的行为。在PHP开发中,通过使用策略模式,我们可以轻松切换算法或逻辑处理方式而无需修改现有代码结构。本文将深入探讨策略模式的定义、结构以及如何在PHP中实现该模式,并通过实际案例展示其应用价值和优势。
28 1
|
29天前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入解析与应用
【10月更文挑战第8天】 在软件开发的浩瀚宇宙中,设计模式如同星辰指引,照亮了代码设计与架构的航道。本文旨在深入探索PHP语境下策略模式(Strategy Pattern)的精髓,不仅剖析其内核原理,还将其融入实战演练,让理论在实践中生根发芽。策略模式,作为解决“如何优雅地封装算法族”的答案,以其独特的灵活性与扩展性,赋予PHP应用以动态变换行为的能力,而无需牵动既有的类结构。
17 2
|
30天前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入解析与实践
在PHP开发中,设计模式是提高代码可读性、可维护性和扩展性的重要工具。本文将深入探讨策略模式这一行为型设计模式,通过分析其定义、结构、使用场景以及在PHP中的实际应用,帮助开发者更好地理解和运用策略模式来优化自己的项目。不同于传统摘要的简洁概述,本文摘要部分将详细阐述策略模式的核心理念和在PHP中的实现方法,为读者提供清晰的指引。