Java使用Function包策略模式,优化业务代码大量if...else语句
目录
场景模拟
Consumer与ToIntBiFunction简介,u>
场景Demo业务代码改造
最终结果
业务代码中,若存在大量无法避免的if...else代码,可以尝试使用JDK8提供的函数式编程包。
场景模拟
设计一个简单的招聘业务:
招聘条件是:男18~60岁,女18~50岁。再根据男女不同年龄段,分配不同的事情任务做。
模拟代码如下
package cn.daydayup.designmode.factorymode.demov4;/*** @author ShangHai* @desc*/
public class Demo {/*** 模拟招聘业务* @param sex 性别* @param age 年龄* @param name 名字*/public void recruit(String sex, int age, String name){if(CommonConstants.MAN.equals(sex)){// 男性if(age > CommonConstants.SIXTY){throw new RuntimeException("年龄不满足");} else if(age > CommonConstants.FORTY_FIVE){this.doSomeThings001(name);} else if(age >= CommonConstants.THIRTY){this.doSomeThings002(name);} else if(age >= CommonConstants.EIGHTEEN){this.doSomeThings003(name);} else {throw new RuntimeException("年龄不满足");}} else if(CommonConstants.WOMAN.equals(sex)) {// 女性if(age > CommonConstants.FIFTY){throw new RuntimeException("年龄不满足");} else if(age >= CommonConstants.THIRTY){this.doSomeThings004(name);} else if(age >= CommonConstants.EIGHTEEN){this.doSomeThings005(name);} else {throw new RuntimeException("年龄不满足");}} else {throw new RuntimeException("性别不满足");}}private void doSomeThings001(String name){System.out.println(name + "[男]年龄45-60");}private void doSomeThings002(String name){System.out.println(name + "[男]年龄30-45");}private void doSomeThings003(String name){System.out.println(name + "[男]年龄18-30");}private void doSomeThings004(String name){System.out.println(name + "[女]年龄30-60");}private void doSomeThings005(String name){System.out.println(name + "[女]年龄18-30");}}
常量代码
package cn.daydayup.designmode.factorymode.demov4;/*** @author ShangHai* @desc*/
public class CommonConstants {public final static int ZERO = 0;public final static int ONE = 1;public final static int TWO = 2;public final static int THRRE = 3;public final static int FOUR = 4;public final static int FIVE = 5;public final static int EIGHTEEN = 18;public final static int THIRTY = 30;public final static int FORTY_FIVE = 45;public final static int FIFTY = 50;public final static int SIXTY = 60;public final static String MAN = "男";public final static String WOMAN = "女";}
main方法执行【控制台:GeGeDa[男]年龄45-60】
public static void main(String[] args) {// 控制台输出: 【GeGeDa[男]年龄45-60】new Demo().recruit(CommonConstants.MAN, 49, "GeGeDa");}
上述的业务方法中,存在较多的if...else条件语句。
若条件维度根据业务需求增多,if...else语句将会不断叠加,业务代码将变得不再优雅。
分析以上业务代码,可采用Function包中的Consumer<T>与ToIntBiFunction<T,U>配合进行改造。
Consumer<T>与ToIntBiFunction<T,U>简介
Consumer<T>
Consumer<T>接口是java.util.function包的其中一个接口,
包含一个核心方法accept(T t),其意义即传入一个参数进行消费,无返回值。
代码测试如下:
package cn.daydayup.designmode.factorymode.demov4.test;import java.util.function.Consumer;/*** @author ShangHai* @desc*/ public class TestConsumer {public static void main(String[] args) {Consumer<String> consumer = a -> {System.out.println("输出参数值:" + a);};// 传入字符串参数consumer.accept("aaaa");}}
以上consumer对象声明的方式,等同于
Consumer<String> consumer = new Consumer<String>() {@Overridepublic void accept(String a) {System.out.println("输出参数值:" + a);}};
main方法执行【控制台:输出参数值:aaaa】
ToIntBiFunction<T,U>
ToIntBiFunction<T,U>接口是java.util.function包的其中一个接口,
包含一个核心方法applyAsInt(T t,U u),其意义即传入两个参数进行消费,返回一个int值。
代码测试如下:
package cn.daydayup.designmode.factorymode.demov4.test;import cn.daydayup.designmode.CommonConstant; import cn.daydayup.designmode.factorymode.demov4.CommonConstants;import java.util.function.ToIntBiFunction;/*** @author ShangHai* @desc*/ public class TestToIntBiFunction {public static void main(String[] args) {// 传入两个String参数,得到一个int值ToIntBiFunction<String, String> toIntBiFunction = (a, b) -> {if(a.equals(b)){return CommonConstants.ONE;} else {return CommonConstants.TWO;}};// 传入两个字符串参数int result = toIntBiFunction.applyAsInt("参数1", "参数2");System.out.println("得到的int值" + result);}}
以上toIntBiFunction对象声明的方式,等同于
ToIntBiFunction<String, String> toIntBiFunction = new ToIntBiFunction<String, String>() {@Overridepublic int applyAsInt(String a, String b) {if(a.equals(b)){return CommonConstants.ONE;} else {return CommonConstants.TWO;}}};
main方法执行【控制台:得到的int值2】
场景Demo业务代码改造
一、if条件&逻辑代码抽离
创建一个策略列表业务执行类RecruitConsumer,
用来存储if标签体内实际的执行方法。
package cn.daydayup.designmode.factorymode.demov4.function;import cn.daydayup.designmode.factorymode.demov4.CommonConstants;import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;/*** @author ShangHai* @desc*/
public class RecruitConsumer {// 策略列表public static final Map<Integer, Consumer<String>> CONSUMER_MAP = new HashMap<>();static {// 根据传入不同的int值,将执行不同方法CONSUMER_MAP.put(CommonConstants.ONE, RecruitConsumer::doSomeThings001);CONSUMER_MAP.put(CommonConstants.TWO, RecruitConsumer::doSomeThings002);CONSUMER_MAP.put(CommonConstants.THRRE, RecruitConsumer::doSomeThings003);CONSUMER_MAP.put(CommonConstants.FOUR, RecruitConsumer::doSomeThings004);CONSUMER_MAP.put(CommonConstants.FIVE, RecruitConsumer::doSomeThings005);}private static void doSomeThings001(String name){System.out.println(name + "[男]年龄45-60");}private static void doSomeThings002(String name){System.out.println(name + "[男]年龄30-45");}private static void doSomeThings003(String name){System.out.println(name + "[男]年龄18-30");}private static void doSomeThings004(String name){System.out.println(name + "[女]年龄30-60");}private static void doSomeThings005(String name){System.out.println(name + "[女]年龄18-30");}}
创建一个"条件收集&策略数值"返回类RecruitToIntBiFunction,
用来收集需求下所有的if分支,且根据if满足的条件返回一个策略列表需要的策略int数值。
package cn.daydayup.designmode.factorymode.demov4.function;import cn.daydayup.designmode.CommonConstant;
import cn.daydayup.designmode.factorymode.demov4.CommonConstants;import java.util.function.ToIntBiFunction;/*** @author ShangHai* @desc*/
public class RecruitToIntBiFunction implements ToIntBiFunction{@Overridepublic int applyAsInt(Object o, Object o2) {if(o==null || o2==null){// 返回0,RecruitConsumer策略列表不具备0策略,不执行任何逻辑return CommonConstants.ZERO;}String sex = o.toString();int age = Integer.parseInt(o2.toString());if(CommonConstants.MAN.equals(sex)){// 男性if(age > CommonConstants.SIXTY){// 返回0,RecruitConsumer策略列表不具备0策略,不执行任何逻辑return CommonConstants.ZERO;} else if(age > CommonConstants.FORTY_FIVE){return CommonConstants.ONE;} else if(age >= CommonConstants.THIRTY){return CommonConstants.TWO;} else if(age >= CommonConstants.EIGHTEEN){return CommonConstants.THRRE;} else {// 返回0,RecruitConsumer策略列表不具备0策略,不执行任何逻辑return CommonConstants.ZERO;}} else if(CommonConstants.WOMAN.equals(sex)) {// 女性if(age > CommonConstants.FIFTY){// 返回0,RecruitConsumer策略列表不具备0策略,不执行任何逻辑return CommonConstants.ZERO;} else if(age >= CommonConstants.THIRTY){return CommonConstants.FOUR;} else if(age >= CommonConstants.EIGHTEEN){return CommonConstants.FIVE;} else {// 返回0,RecruitConsumer策略列表不具备0策略,不执行任何逻辑return CommonConstants.ZERO;}} else {// 返回0,RecruitConsumer策略列表不具备0策略,不执行任何逻辑return CommonConstants.ZERO;}}}
二、业务逻辑代码改造(最终仅需两行)
package cn.daydayup.designmode.factorymode.demov4;import cn.daydayup.designmode.factorymode.demov4.function.RecruitConsumer;
import cn.daydayup.designmode.factorymode.demov4.function.RecruitToIntBiFunction;/*** @author ShangHai* @desc*/
public class Demo {/*** 模拟招聘业务* @param sex 性别* @param age 年龄* @param name 名字*/public void recruit(String sex, int age, String name){// 将if条件所需参数传入,得到策略int数值int strategyInt = new RecruitToIntBiFunction().applyAsInt(sex, age);// 将策略int数值传入策略列表,consumer会自动执行对应的策略方法RecruitConsumer.CONSUMER_MAP.get(strategyInt).accept(name);}public static void main(String[] args) {// 控制台输出 ShangHai[男]年龄18-30new Demo().recruit(CommonConstants.MAN, 18, "ShangHai");}
}
main方法执行【控制台:ShangHai[男]年龄18-30】
最终结果
业务方法经过"Funtion包与策略模式"改造后,
代码变得简洁;
业务方法不再关注if如何实现,交由定义好的策略消费即可;
if...else分支语句及业务实际执行方法分类被收集,代码整体层次变得规范。
Java使用Function包策略模式,优化业务代码大量if...else语句相关推荐
- java策略管理_详解Java编程中的策略模式
策略模式属于对象的行为模式.其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换.策略模式使得算法可以在不影响到客户端的情况下发生变化. 策略模式的结构 策略模式 ...
- 深入学习Java8 Lambda (default method, lambda, function reference, java.util.function 包)
Java 8 Lambda .MethodReference.function包 多年前,学校讲述C#时,就已经知道有Lambda,也惊喜于它的方便,将函数式编程方式和面向对象式编程基于一身.此外在使 ...
- 策略模式java 用例_java策略模式简单用例
运用java策略模式一个小程序 /** * */ package Strategy; import java.util.Arrays; /** * @author HuangRong * @Funti ...
- java.util.function包
目录 Supplier 参数个数扩展 参数类型扩展 特殊变形 Function,r> 参数个数扩展 参数类型扩展 特殊变形 Consumer 参数个数扩展 参数类型扩展 特殊变形 Predica ...
- java.util接口_Java 8中java.util.function包中的谓词和使用者接口
java.util接口 在上一篇文章中,我写了关于Function接口的内容 ,它是java.util.package的一部分. 我还提到了Predicate接口,它是同一包的一部分,在这篇文章中,我 ...
- java.util接口_函数接口– Java 8中java.util.function包中的函数接口
java.util接口 我以前写过有关功能接口及其用法的文章. 如果您正在探索要成为Java 8一部分的API,尤其是那些支持lambda表达式的API,您会发现很少的接口,例如Function,Su ...
- Java 8中java.util.function包中的谓词和使用者接口
在我以前的文章中,我写了关于Function接口的内容 ,它是java.util.package的一部分. 我还提到了Predicate接口,它是同一包的一部分,在这篇文章中,我将向您展示如何使用Pr ...
- 函数接口– Java 8中java.util.function包中的函数接口
我以前写过有关功能接口及其用法的文章. 如果您正在探索要成为Java 8一部分的API,尤其是那些支持lambda表达式的API,您会发现很少的接口,例如Function,Supplier,Consu ...
- Java的日期与时间之如何计算业务代码的运行时间呢?
转自: Java的日期与时间之如何计算业务代码的运行时间呢? 下文笔者讲述计算运行时间的方法分享,如下所示 实现思路:在业务开始时间和结束时间都加入获取时间的方法然后相减即可得到运行时间 例: lon ...
最新文章
- 如何解决ORA-12547错误!
- windows msys编译64位x264和ffmpeg
- mac python request ssl错误解决
- webpack + react 使用 eslint
- 如何处理SAP Launchpad上tile打不开的问题
- bat 两个文本字符替换_Excel中最全最实用的文本函数公式大全
- Docker系列(三)容器的基本操作
- SQL项目实战练习:淘宝用户行为数据分析实战
- 游戏公司的交互设计人员一般都做什么工作?
- nba2k21那个php是啥,NBA2K21不同版本区别介绍 各版本详细信息及奖励内容一览
- 网易面试题,小易沉迷游戏
- Android自定义九宫格图案解锁
- linux虚拟机ping不通外网问题
- java sapi.spvoice_SAPI使用总结——SpVoice的使用方法
- 猿辅导python编程课网课怎么样_猿辅导网课怎么样,一个过来人经历告诉你
- 简单了解计算机基础知识
- 2020 年校招,最值得加入的互联网公司有哪些?
- mysql 金额_Mysql中金额使用DECIMAL类型
- Python代码出现UnicodeEncodeError问题
- 配电室环境远程监控物联网方案