策略模式实现方式之Map<K,Function>

2023-09-21 10:56:36

策略模式实现方式之Map<K,Function>

小概念

场景

  • 我们有一个对象
  • 对象有一个行为
  • 该行为在不同场景中有不同的表现形式

策略模式

  • 定义了一系列算法
  • 封装了每个算法
  • 这一系列的算法可互换代替

代码实现

定义一个对象行为表现形式枚举

    //定义一个对象行为表现形式枚举
    public enum AdApplyTypeEnum implements BaseEnum<Integer> {

    /**
     * 价值鉴定
     */
    WORTH(1, "价值鉴定","JZJD",3);

    Integer value;

    /**
     * 名称
     */
    String name;

    /**
     * 申请单编号编码前缀
     */
    String code;

    /**
     * 鉴定类型对应工作流模板类型
     */
    Integer wfType;

    AdApplyTypeEnum(Integer value, String name, String code,Integer wfType) {
        this.value = value;
        this.name = name;
        this.code = code;
        this.wfType = wfType;
    }

    /**
     * 获取枚举值
     *
     * @return value
     */
    @Override
    public Integer getValue() {
        return value;
    }

    /**
     * 根据枚举值获取枚举类型
     *
     * @param value 枚举值
     * @return FormStateEnum
     */
    public static AdApplyTypeEnum valueOf(Integer value) {
        for (AdApplyTypeEnum typeEnum : AdApplyTypeEnum.values()) {
            if (typeEnum.getValue().equals(value)) {
                return typeEnum;
            }
        }
        return AdApplyTypeEnum.OTHER;
    }
}

定义每种表现形式

/**
 *价值
 **/
private boolean updateWorth(AdApplyDataPO adApplyDataPO) {

}
/**
 * 销毁
 **/
private boolean updateDestroy(AdApplyDataPO adApplyDataPO) {
        
}

封装Map<K,Funtion> 和 初始化算法的对应的函数

    /**
     * 鉴定完成业务逻辑
     */
    private final Map<AdApplyTypeEnum, Function<AdApplyDataPO, Boolean>> applyTypeBusinessLogicMap = new HashMap<>(16);

    /**
     * 初始化鉴定类型对应鉴定完成后业务逻辑
     */
    @PostConstruct
    private void initApplyTypeBusinessLogicMap() {
        applyTypeBusinessLogicMap.put(AdApplyTypeEnum.WORTH, this::updateWorth);
        applyTypeBusinessLogicMap.put(AdApplyTypeEnum.DESTROY, this::updateDestroy);
        applyTypeBusinessLogicMap.put(AdApplyTypeEnum.DECRYPT, this::updateDecrypt);
        applyTypeBusinessLogicMap.put(AdApplyTypeEnum.OPEN, this::updateOpen);
    }

具体应用

    //参数
    AdApplyDataPO adApplyDataPO;
    //K值
    AdApplyTypeEnum adApplyType;
    //调用
    applyTypeBusinessLogicMap.get(adApplyType).apply(adApplyDataPO);

其他实现方式

利用java的多态特性

  • 使用接口的多实现
  • 子类继承父类重写父类的方法
代码实现
//StrategyExample test application

class StrategyExample {

    public static void main(String[] args) {

        Context context;

        // Three contexts following different strategies
        context = new Context(new FirstStrategy());
        context.execute();

        context = new Context(new SecondStrategy());
        context.execute();

        context = new Context(new ThirdStrategy());
        context.execute();

    }

}

// The classes that implement a concrete strategy should implement this

// The context class uses this to call the concrete strategy
interface Strategy {

    void execute();
    
}

// Implements the algorithm using the strategy interface
class FirstStrategy implements Strategy {

    public void execute() {
        System.out.println("Called FirstStrategy.execute()");
    }
    
}

class SecondStrategy implements Strategy {

    public void execute() {
        System.out.println("Called SecondStrategy.execute()");
    }
    
}

class ThirdStrategy implements Strategy {

    public void execute() {
        System.out.println("Called ThirdStrategy.execute()");
    }
    
}

// Configured with a ConcreteStrategy object and maintains a reference to a Strategy object
class Context {

    Strategy strategy;

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

    public void execute() {
        this.strategy.execute();
    }

}

还有一种在枚举中实现

但是这种我很少见到别人使用,不知道是不符合规范还是什么原因
不知道还有没有其他更好用的方式了

实现示例
enum PaymentStrategy {
    CREDIT_CARD {
        @Override
        void pay(int amount) {
            System.out.println("Paid " + amount + " dollars by credit card");
        }
    },
    PAYPAL {
        @Override
        void pay(int amount) {
            System.out.println("Paid " + amount + " dollars by PayPal");
        }
    };

    abstract void pay(int amount);
}

public class ShoppingCart {
    private PaymentStrategy paymentStrategy;

    public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
        this.paymentStrategy = paymentStrategy;
    }

    public void checkout(int amount) {
        paymentStrategy.pay(amount);
    }

    public static void main(String[] args) {
        ShoppingCart cart = new ShoppingCart();
        cart.setPaymentStrategy(PaymentStrategy.CREDIT_CARD);
        cart.checkout(100);

        cart.setPaymentStrategy(PaymentStrategy.PAYPAL);
        cart.checkout(50);
    }
}
更多推荐

c++ 归并排序

归并排序算法时间复杂度较为稳定,一般为nlogn,而快速排序受源数组排序影响较大,今天来学习归并排序。一.归并排序代码首先上代码:可以直接运行#include<bits/stdc++.h>usingnamespacestd;voidinsertsort(vector<int>&nums,intleft,intmid,i

中兴面试-Java开发

1、Springboot框架,yarn是怎么配置的SpringBoot本身没有直接的配置或集成与YARN(YetAnotherResourceNegotiator)的特性,YARN是Hadoop的一个资源管理和作业调度平台。如果你想在YARN上运行SpringBoot应用,你需要考虑将你的SpringBoot应用打包为

分布式AKF拆分原则

目录1前言2什么是AKF3如何基于AKFX轴扩展系统?4如何基于AKFY轴扩展系统?5如何基于AKFZ轴扩展系统?6小结1前言当我们需要分布式系统提供更强的性能时,该怎样扩展系统呢?什么时候该加机器?什么时候该重构代码?扩容时,究竟该选择哈希算法还是最小连接数算法,才能有效提升性能?在面对Scalability可伸缩性

大数据-玩转数据-Flink恶意登录监控

一、恶意登录对于网站而言,用户登录并不是频繁的业务操作。如果一个用户短时间内频繁登录失败,就有可能是出现了程序的恶意攻击,比如密码暴力破解。因此我们考虑,应该对用户的登录失败动作进行统计,具体来说,如果同一用户(可以是不同IP)在2秒之内连续两次登录失败,就认为存在恶意登录的风险,输出相关的信息进行报警提示。这是电商网

图解Raft协议

前言分布式系统设计中,在极大提高可用性、容错性的同时,带来了一致性问题(CAP理论),Raft协议就是解决分布式中的一致性问题。最近研究了Raft协议,谈谈自己对Raft协议的理解。希望这篇文章能够帮助大家理解。raft协议是什么?Raft协议是一种分布式一致性算法(共识算法),共识就是多个节点对某一个事件达成一致的算

网络编程套接字 | TCP套接字

前面的文章中我们使用UDP套接字编写了四个版本,不同的UDP服务器,在本文中我们将要对TCP套接字进行几个不同的版本的代码的编写,首先测试一下TCP套接字的代码,然后是将这个版本进行修改成多进程版本的,再将代码修改成多线程版本的,最后在编写一个线程池版本的代码。在编写TCP套接字之前我们会使用如下的一些APIsocke

QT基础教程(QT中的文件操作)

文章目录前言一、文件操作方法二、QFileInfo类四、QTemporaryFile类总结前言本篇文章我们来讲解QT中的文件操作,文件操作对于QT来说是非常重要的一个点,那么下面的话将给大家详细的讲解QT中的文件操作。一、文件操作方法在QT中,文件操作是通过Qt的文件和目录处理类来完成的。以下是一些常用的文件操作功能:

FLASK中的鉴权的插件Flask-HTTPAuth

在Web应用中,我们经常需要保护我们的api,以避免非法访问。比如,只允许登录成功的用户发表评论等。Flask-HTTPAuth扩展可以很好地对HTTP的请求进行认证,不依赖于Cookie和Session。本文主要介绍两种认证的方式:基于密码和基于令牌(token)。1、安装$pipinstallFlask-HTTPA

数学建模——微分方程介绍

一、基础知识1、一阶微分方程称为一阶微分方程。y(x0)=y0为定解条件。其常规求解方法:(1)变量分离再两边积分就可以求出通解。(2)一阶线性求解公式通解公式:有些一阶微分方程需要通过整体代换,比如u=x+y,u=xy,u=x/y,u=1/yn等化为以上两种类型求解后再还原。2、二阶常系数微分方程【1】【2】【1】为

Java运行时数据区域

运行时数据区域Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。根据《Java虚拟机规范》的规定,Java虚拟机所管理的内存将会包括以下几个运行时数据区域:程序计数器程序计数器(ProgramCounterRegister)是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号

5.10.WebRTC接口宏

那今天呢?我给大家介绍一下webrtc的接口宏,那之所以在现成的章节中要介绍接口宏。是由于接口在调用的过程中啊,会发生线程的切换,所以把接口宏这部分知识我们放在线程这一章还算比较合适的。那另外呢,我们对于接口宏的介绍可能要花费三节到四节的时间,那之所以要用这么大的篇幅来介绍接口宏,是由于接口宏本身是比较复杂的。里边儿涉

热文推荐