GOF23设计模式-行为型模式6-策略模式(Strategy)

定义

它定义了算法家族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化,不会影响到使用算法的客户。
允许用户从该算法族中任选一个算法解决某一问题,同时可以方便的更换算法或者新增算法。
本质:分离算法,选择实现。

结构图

在这里插入图片描述

  • Strategy:策略类,定义所有支持算法的接口。
  • ConcreteStrategy:具体的算法策略或行为,实现Strategy。
  • Context:上下文,用一个ConcreteStrategy来配置,维护一个对Strategy的引用。

模拟场景

某一市场人员接到单价厚的报价策略(CRM系统中常见问题),实际中很复杂,现做如下分类:

  • 普通用户小批量订单
  • 普通用户大批量订单
  • 老用户小批量订单
  • 老用户大批量订单

具体选用那种报价策略,就看是什么用户了,此时采用策略模式来实现。

代码实现

  1. 创建策略接口Strategy
/**
 * User:tumbler
 * Desc:策略模式--策略接口:定义所有支持的算法的公共接口
 */
public interface Strategy {
    /**
     * 传入原价,通过算法后返回报价
     * @param standardPrice
     * @return
     */
    double getPrice(double standardPrice);
}
  1. 创建具体策略算法类:普通客户小批量,普通客户大批量,老客户小批量,老客户大批量。
/**
 * User:tumbler
 * Desc:策略模式--具体算法类,实现策略Strategy接口
 *       模拟普通用户小批量购物:原价卖出
 */
public class NewCustomerFewStrategy implements Strategy {
    @Override
    public double getPrice(double standardPrice) {
        System.out.println("普通用户小批量:不打折,原价卖出!");
        return standardPrice;
    }
}
/**
 * User:tumbler
 * Desc:策略模式--具体算法类,实现策略Strategy接口
 *       模拟普通用户大批量购物:打9折
 */
public class NewCustomerManyStrategy implements Strategy {
    @Override
    public double getPrice(double standardPrice) {
        System.out.println("普通用户大批量:打9折!");
        return standardPrice * 0.9;
    }
}
/**
 * User:tumbler
 * Desc:策略模式--具体算法类,实现策略Strategy接口
 *       模拟老客户小批量购物:打8折
 */
public class OldCustomerFewStrategy implements Strategy {
    @Override
    public double getPrice(double standardPrice) {
        System.out.println("老客户小批量:打8折!");
        return standardPrice * 0.8;
    }
}
/**
 * User:tumbler
 * Desc:策略模式--具体算法类,实现策略Strategy接口
 *       模拟老客户大批量购物:打7折
 */
public class OldCustomerManyStrategy implements Strategy {
    @Override
    public double getPrice(double standardPrice) {
        System.out.println("老客户大批量:打7折!");
        return standardPrice * 0.7;
    }
}
  1. 上下文类Context
/**
 * User:tumbler
 * Desc:策略模式--上下文类
 *      负责和具体的策略类交互
 *      使具体的算法和客户端调用分离了,算法可以独立于客户端独立的变化
 *
 *      持有了策略类对象:可以通过构造方法,也可通过setter方法,如果使用Spring可用配置文件或者注解注入
 */
public class Context {

    private Strategy strategy;

    public Context(Strategy strategy) {
        this.strategy = strategy;
    }

    public void setStrategy(Strategy strategy) {
        this.strategy = strategy;
    }

    /**
     * 打印报价
     * @param standardPrice
     */
    public void printPrice(double standardPrice) {
        System.out.println("最终报价===" + strategy.getPrice(standardPrice));
    }
}
  1. 测试类Client
/**
 * User:tumbler
 * Desc:策略模式--测试
 */
public class Client {
    public static void main(String[] args) {
        Strategy s1 = new OldCustomerManyStrategy();
        Context context = new Context(s1);
        context.printPrice(998);
    }
}

运行结果:

老客户大批量:打7折!
最终报价===698.5999999999999
  • UML图
    在这里插入图片描述

开发中常见场景

  • JavaSE中GUI编程中的布局管理
  • Spring框架中Resource接口,资源访问策略
  • javax.servlet.http.HttpServlet#service()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值