如何理解和运用策略模式

点击上方 "编程技术圈"关注, 星标或置顶一起成长

后台回复“大礼包”有惊喜礼包!

日英文

Mistakes are part of life. You should be more worried if you didn't make them because that means you aren't growing or learning.

犯错是人生的一部分,一旦你不再犯错,就应该开始警惕了,因为这意味着你没有进步,没有学到新的东西。

每日掏心话

一个人势必会从受挫中成长,如果他能做到这一点,那么他的个人能力就会得以发展。

责编:乐乐 | 来自:溪~源链接:blog.csdn.net/xuan_lu/article/details/114417396

编程技术圈(ID:study_tech)第 1218 次推文

往日回顾:B站惹上事儿了!

     

   正文   

定义首先介绍一下众多博客文章中提到的策略模式的概念,针对于文章结构构成,请允许小编在此处再细说一下。
策略模式:百度百科中引述为:指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。
策略模式是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理。策略模式通常把一个系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类。用一句话来说,就是:“准备一组算法,并将每一个算法封装起来,使得它们可以互换”。【此处的算法,大家可以理解为解决业务需求的方法。】
对于这些概念大家理解起来或许有些抽象,耐心往下读,相信大家肯定会有所收获。
组成环境(Context)角色: 持有一个Strategy的引用。抽象策略(Strategy)角色: 这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。具体策略(ConcreteStrategy)角色: 包装了相关的算法或行为。理解对于设计模式中的策略模式,大家众多的解释可能侧重与解决if…else,switch-cas这种条件语句的优化,小编简单谈一下我在项目中实际应用和理解吧;对于策略模式按照上面给予的定义理解,是将多个业务节点具备的共同算法再次顶层抽象为接口,处理不同业务需求时,则产生的行为不同,即具体行为由其实现类解决;注重词:相同算法,,顶层抽出。
再简单举例说明一下,比如工作的OA系统中,流程节点具体相同的功能:提交,回退,撤回等等(抽象策略类);但是每个流程节点所实现的功能不同(具体策略类);
实现小编以我们日常生活中最常见的支付方式为例,解答策略模式的应用。
无论使用xiaomi,huawei,apple均存在相同的行为(算法),例如:支付方式不同,客户端享受的优惠力度不等。故我们将支付作为共同的接口抽象出来。
UML抽象策略类将支付作为共同算法,顶层抽象。
/**
 * @author wx
 * @date 2021/03/05 1:50 下午
 */
public interface PayStrategy {
    void pay(double money);
}
具体策略类MiPAY
/**
 * @author wx
 * @date 2021/03/05 1:51 下午
 */
public class MiPayStrategy implements PayStrategy{
    @Override
    public void pay(double money) {
        double payMoney = money * 0.87;
        double discountMoney = money - payMoney;
        System.out.println("使用Mi pay成功支付" + payMoney + "元,优惠" + discountMoney + "元");
    }
}
HuaWeiPAY
/**
 * @author wx
 * @date 2021/03/05 1:50 下午
 */
public class HuaWeiPayStrategy implements PayStrategy{
    @Override
    public void pay(double money) {
        double payMoney = money * 0.85;
        double discountMoney = money - payMoney;
        System.out.println("使用HuaWei pay成功支付" + payMoney + "元,优惠" + discountMoney + "元");
    }
}
ApplePAY
/**
 * @author wx
 * @date 2021/03/05 1:52 下午
 */
public class ApplePayStrategy implements PayStrategy{
    @Override
    public void pay(double money) {
        double payMoney = money * 0.82;
        double discountMoney = money - payMoney;
        System.out.println("使用Apple pay成功支付" + payMoney + "元,优惠" + discountMoney + "元");
    }
}
环境类供客户端调用,并选择具体策略
搜索公众号后端架构师后台回复“架构整洁”,获取一份惊喜礼包。
/**
 * @author wx
 * @date 2021/03/05 1:53 下午
 */
public class PayContext {
    //依赖策略接口属性
    private PayStrategy payStrategy;

    public void setPayStrategy(PayStrategy payStrategy) {
        this.payStrategy = payStrategy;
    }

    /**
     * 提供外部访问方法
     * @param money
     */
    public void payMoney(double money) {
        payStrategy.pay(money);
    }
}
客户端客户端则已知选择的支付方式,可以服务端依据不同支付策略选择折扣。
/**
 * @author wx
 * @date 2021/03/05 1:59 下午
 */
public class PayClient {
    public static void main(String[] args) {
        //创建支付上下文
        PayContext payContext = new PayContext();
        //创建支付策略,客户端已知存在具体策略
        PayStrategy miPayStrategy = new MiPayStrategy();
        payContext.setPayStrategy(miPayStrategy);
        payContext.payMoney(100);
        System.out.println("-------改变支付策略--------");
        PayStrategy applePayStrategy = new ApplePayStrategy();
        payContext.setPayStrategy(applePayStrategy);
        payContext.payMoney(100);

    }
}
执行结果:
理解了策略模式的使用,下面简单谈谈该模式的优点和缺点:
优点:
毫不疑问复合设计模式中的开闭原则,新增支付方式则扩展策略类即可,无须改动其他策略类的实现;消除if-else类似的判断语句,整合代码结构,符合代码整洁之道;缺点:
从类的数量上而言,若策略选择很多,则造成策略类数量增加;所有策略类都需要对外暴露。即客户端必须知道所有的策略类,并自行决定使用哪一个策略类,故不得不向客户暴露具体的实现。类比其他模式策略模式和状态模式:
一、执行方式:策略模式:客户端策略条件选择只执行一次;状态模式:随着实例参数(对象实例的状态)的改变不停地更改执行模式。简言之,策略模式只是在对象初始化的时候更改执行模式,而状态模式是根据对象实例的周期时间而动态地改变对象实例的执行模式。
二、环境类策略模式:环境类自己选择一个具体策略类,具体策略类无须关心环境类 ;状态模式:环境类由于外在因素需要放进一个具体状态中,以便通过其方法实现状态的切换 ,因此环境类和状态类之间存在一种双向的关联关系。简言之,使用策略模式时客户端需要知道所选的具体策略是哪一个;
而使用状态模式时, 客户端无须关心具体状态 ,环境类的状态会根据用户的操作自动转换。
PS:欢迎在留言区留下你的观点,一起讨论提高。如果今天的文章让你有新的启发,欢迎转发分享给更多人。版权申明:内容来源网络,版权归原创者所有。除非无法确认,我们都会标明作者及出处,如有侵权烦请告知,我们会立即删除并表示歉意。谢谢!

欢迎加入后端架构师交流群,在后台回复“学习”即可。

最近面试BAT,整理一份面试资料《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。在这里,我为大家准备了一份2021年最新最全BAT等大厂Java面试经验总结。
别找了,想获取史上最简单的Java大厂面试题学习资料
扫下方二维码回复「面试」就好了


猜你还想看
阿里、腾讯、百度、华为、京东最新面试题汇集
Token多平台身份认证架构设计思路
成人版“抖音”终于还是凉了,画面简直不可描述

拆解1968年的美国军用电脑,真的怀疑是“穿越”啊!

嘿,你在看吗?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值