优化if...else...语句
写代码的时候经常遇到这样的场景:根据某个字段值来进行不同的逻辑处理。例如,不同的会员等级在购物时有不同的折扣力度。如果会员的等级很多,那么代码中与之相关的if...elseif...else...会特别长,而且每新增一种等级时需要修改原先的代码。可以用策略模式来优化,消除这种场景下的if...elseif...else...,使代码看起来更优雅。

首先,定义一个接口
/**
* 会员服务
*/
public interface VipService {
void handle();
}
然后,定义实现类
/**
* 白银会员
*/
public class SilverVipService implements VipService {
@Override
public void handle() {
System.out.println("白银");
}
}
/**
* 黄金会员
*/
public class GoldVipService implements VipService {
@Override
public void handle() {
System.out.println("黄金");
}
}
最后,定义一个工厂类,目的是当传入一个会员等级后,返回其对应的处理类
public class VipServiceFactory {
private static Map<String, VipService> vipMap = new ConcurrentHashMap<>();
public static void register(String type, VipService service) {
vipMap.put(type, service);
}
public static VipService getService(String type) {
return vipMap.get(type);
}
}
为了建立会员等级和与之对应的处理类之间的映射关系,这里通常可以有这么几种处理方式:
方式一:实现类手动注册
可以实现InitializingBean接口,或者在某个方法上加@PostConstruct注解
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
/**
* 白银会员
*/
@Component
public class SilverVipService implements VipService, InitializingBean {
@Override
public void handle() {
System.out.println("白银");
}
@Override
public void afterPropertiesSet() throws Exception {
VipServiceFactory.register("silver", this);
}
}
/**
* 黄金会员
*/
@Component
public class GoldVipService implements VipService, InitializingBean {
@Override
public void handle() {
System.out.println("黄金");
}
@Override
public void afterPropertiesSet() throws Exception {
VipServiceFactory.register("gold", this);
}
}
方式二:从Spring容器中直接获取Bean
public interface VipService {
void handle();
String getType();
}
/**
* 白银会员
*/
@Component
public class SilverVipService implements VipService {
@Override
public void handle() {
System.out.println("白银");
}
@Override
public String getType() {
return "silver";
}
}
/**
* 黄金会员
*/
@Component
public class GoldVipService implements VipService {
@Override
public void handle() {
System.out.println("黄金");
}
@Override
public String getType() {
return "gold";
}
}
/**
* 上下文
*/
@Component
public class VipServiceFactory implements ApplicationContextAware {
private static Map<String, VipService> vipMap = new ConcurrentHashMap<>();
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
Map<String, VipService> map = applicationContext.getBeansOfType(VipService.class);
map.values().forEach(service -> vipMap.put(service.getType(), service));
}
public static VipService getService(String type) {
return vipMap.get(type);
}
}
/**
* 测试
*/
@SpringBootTest
class DemoApplicationTests {
@Test
void contextLoads() {
VipServiceFactory.getService("silver").handle();
}
}
方式三:反射+自定义注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MemberLevel {
String value();
}
@MemberLevel("silver")
@Component
public class SilverVipService implements VipService {
@Override
public void handle() {
System.out.println("白银");
}
}
@MemberLevel("gold")
@Component
public class GoldVipService implements VipService {
@Override
public void handle() {
System.out.println("黄金");
}
}
/**
* 上下文
*/
@Component
public class VipServiceFactory implements ApplicationContextAware {
private static Map<String, VipService> vipMap = new ConcurrentHashMap<>();
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
// Map<String, VipService> map = applicationContext.getBeansOfType(VipService.class);
Map<String, Object> map = applicationContext.getBeansWithAnnotation(MemberLevel.class);
for (Object bean : map.values()) {
if (bean instanceof VipService) {
String type = bean.getClass().getAnnotation(MemberLevel.class).value();
vipMap.put(type, (VipService) bean);
}
}
}
public static VipService getService(String type) {
return vipMap.get(type);
}
}
完整示例代码
/**
* 结算业务种类
* @Author: ChengJianSheng
* @Date: 2023/1/16
*/
@Getter
public enum SettlementBusiType {
RE1011("RE1011", "转贴现"),
RE4011("RE4011", "买断式贴现"),
RE4021("RE4021", "回购式贴现"),
RE4022("RE4022", "回购式贴现赎回");
// ......
private String code;
private String name;
SettlementBusiType(String code, String name) {
this.code = code;
this.name = name;
}
}
/**
* 结算处理器
* @Author: ChengJianSheng
* @Date: 2023/1/16
*/
public interface SettlementHandler {
/**
* 清算
*/
void handle();
/**
* 获取业务种类
*/
SettlementBusiType getBusiType();
}
/**
* 转贴现结算处理
*/
@Component
public class RediscountSettlementHandler implements SettlementHandler {
@Override
public void handle() {
System.out.println("转贴现");
}
@Override
public SettlementBusiType getBusiType() {
return SettlementBusiType.RE1011;
}
}
/**
* 买断式贴现结算处理
*/
@Component
public class BuyoutDiscountSettlementHandler implements SettlementHandler {
@Override
public void handle() {
System.out.println("买断式贴现");
}
@Override
public SettlementBusiType getBusiType() {
return SettlementBusiType.RE4011;
}
}
/**
* 默认处理器
* @Author: ChengJianSheng
* @Date: 2023/1/16
*/
@Component
public class DefaultSettlementHandler implements /*SettlementHandler,*/ ApplicationContextAware {
private static Map<SettlementBusiType, SettlementHandler> allHandlerMap = new ConcurrentHashMap<>();
public static SettlementHandler getHandler(SettlementBusiType busiType) {
return allHandlerMap.get(busiType);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
Map<String, SettlementHandler> map = applicationContext.getBeansOfType(SettlementHandler.class);
map.values().forEach(e -> allHandlerMap.put(e.getBusiType(), e));
}
}
@SpringBootTest
class Demo2023ApplicationTests {
@Test
void contextLoads() {
SettlementHandler handler = DefaultSettlementHandler.getHandler(SettlementBusiType.RE1011);
if (null != handler) {
handler.handle();
}
}
}
优化if...else...语句的更多相关文章
- [MySQL性能优化系列]LIMIT语句优化
1. 背景 假设有如下SQL语句: SELECT * FROM table1 LIMIT offset, rows 这是一条典型的LIMIT语句,常见的使用场景是,某些查询返回的内容特别多,而客户端处 ...
- SQL Server数据库性能优化之SQL语句篇【转】
SQL Server数据库性能优化之SQL语句篇http://www.blogjava.net/allen-zhe/archive/2010/07/23/326927.html 近期项目需要, 做了一 ...
- MSSQL优化之——查看语句执行情况
MSSQL优化之——查看语句执行情况 在写SQL语句时,必须知道语句的执行情况才能对此作出优化.了解SQL语句的执行情况是每个写程序的人必不可少缺的能力.下面是对查询语句执行情况的方法介绍. 一.设置 ...
- 数据库的优化(表优化和sql语句优化)
在这里主要是分为表设计优化和sql语句优化两方面来实现. 首先的是表设计优化: 1.数据行的长度不要超过8020字节.如果是超过这个长度的话这条数据会占用两行,减低查询的效率. 2.能用数字类型就不要 ...
- 优化 JS 条件语句的 5 个技巧
优化 JS 条件语句的 5 个技巧 原创: 前端大全 前端大全 昨天 (给前端大全加星标,提升前端技能) 编译:伯乐在线/Mr.Dcheng http://blog.jobbole.com/11467 ...
- 浅谈mysql配置优化和sql语句优化【转】
做优化,我在这里引用淘宝系统分析师蒋江伟的一句话:只有勇于承担,才能让人有勇气,有承担自己的错误的勇气.有承担错误的勇气,就有去做事得勇气.无论做什么事,只要是对的,就要去做,勇敢去做.出了错误,承担 ...
- Oracle性能优化之SQL语句
1.SQL语句执行过程 1.1 SQL语句的执行步骤 1)语法分析,分析语句的语法是否符合规范,衡量语句中各表达式的意义. 2)语义分析,检查语句中涉及的所有数据库对象是否存在,且用户有相应的权限. ...
- 数据库性能优化之SQL语句优化
一.问题的提出 在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的编写等是体会不出SQL语句各种写法的性能优劣,但是如果将应用系统提交实际应用后,随着数据库中数据的增加,系统 ...
- ORACLE性能优化之SQL语句优化
版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 操作环境:AIX +11g+PLSQL 包含以下内容: 1. SQL语句执行过程 2. 优化器及执行计划 3. 合 ...
- SQL Server优化之SQL语句优化
一切都是为了性能,一切都是为了业务 一.查询的逻辑执行顺序 (1) FROM left_table (3) join_type JOIN right_table (2) ON join_conditi ...
随机推荐
- java 入土--集合详解
java 集合 集合是对象的容器,实现了对对象的常用的操作,类似数组功能. 和数组的区别: 数组长度固定,集合长度不固定 数组可以存储基本类型和引用类型,集合只能存储引用类型 使用时需要导入类 Col ...
- 知识图谱顶会论文(ACL-2022) PKGC:预训练模型是否有利于KGC?可靠的评估和合理的方法
PKGC:预训练模型是否有利于KGC?可靠的评估和合理的方法 论文地址:Do Pre-trained Models Benefit Knowledge Graph Completion? A Reli ...
- flutter系列之:永远不用担心组件溢出的Wrap
目录 简介 Row和Column的困境 Wrap组件详解 总结 简介 我们在flutter中使用能够包含多个child的widget的时候,经常会遇到超出边界范围的情况,尤其是在Column和Row的 ...
- JUC中的AQS底层详细超详解
摘要:当你使用java实现一个线程同步的对象时,一定会包含一个问题:你该如何保证多个线程访问该对象时,正确地进行阻塞等待,正确地被唤醒? 本文分享自华为云社区<JUC中的AQS底层详细超详解,剖 ...
- 【pytest官方文档】解读- 开发可pip安装的第三方插件
在上一篇的 hooks 函数分享中,开发了一个本地插件示例,其实已经算是在编写插件了.今天继续跟着官方文档学习更多知识点. 一个插件包含一个或多个钩子函数,pytest 正是通过调用各种钩子组成的插件 ...
- 【jmeter】将“察看结果树”中的数据保存到本地
操作说明: 1. "察看结果树"页面,[配置]导出项: 2. "察看结果树"页面,[文件名]选框输入导出文件及路径: 3. 点击jmeter[启动]按钮,响应 ...
- Seata Server 1.5.2 源码学习
Seata 包括 Server端和Client端.Seata中有三种角色:TC.TM.RM,其中,Server端就是TC,TM和RM属Client端.Client端的源码学习上一篇已讲过,详见 < ...
- Docker | 专栏文章整理🎉🎉
Docker Docker系列文章基本已经更新完毕,这是我从去年的学习笔记中整理出来的. 笔记稍微有点杂乱.随意,把它们整理成文章花费了不少力气.整理的过程也是我的一个再次学习的过程,同时也是为了方便 ...
- DHorse系列文章之镜像制作
DHorse系列文章之镜像制作 制作镜像常用的工具 使用Docker制作镜像 1.使用docker commit制作 该命令使用比较简单,可以自行网上搜索教程. 2.使用Dockerfile制作 这种 ...
- PP视频(PPTV聚力)web接口分析
前言 前几天我想看一个番剧, 正好搜索到了 PP视频,我才知道PP视频就是PPTV聚力,我想把番剧下载下来,结果发现视频竟然不是m3u8格式,而是多段mp4,所以简单的写了个脚本,可以在不登录的情况下 ...