写代码的时候经常遇到这样的场景:根据某个字段值来进行不同的逻辑处理。例如,不同的会员等级在购物时有不同的折扣力度。如果会员的等级很多,那么代码中与之相关的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...语句的更多相关文章

  1. [MySQL性能优化系列]LIMIT语句优化

    1. 背景 假设有如下SQL语句: SELECT * FROM table1 LIMIT offset, rows 这是一条典型的LIMIT语句,常见的使用场景是,某些查询返回的内容特别多,而客户端处 ...

  2. SQL Server数据库性能优化之SQL语句篇【转】

    SQL Server数据库性能优化之SQL语句篇http://www.blogjava.net/allen-zhe/archive/2010/07/23/326927.html 近期项目需要, 做了一 ...

  3. MSSQL优化之——查看语句执行情况

    MSSQL优化之——查看语句执行情况 在写SQL语句时,必须知道语句的执行情况才能对此作出优化.了解SQL语句的执行情况是每个写程序的人必不可少缺的能力.下面是对查询语句执行情况的方法介绍. 一.设置 ...

  4. 数据库的优化(表优化和sql语句优化)

    在这里主要是分为表设计优化和sql语句优化两方面来实现. 首先的是表设计优化: 1.数据行的长度不要超过8020字节.如果是超过这个长度的话这条数据会占用两行,减低查询的效率. 2.能用数字类型就不要 ...

  5. 优化 JS 条件语句的 5 个技巧

    优化 JS 条件语句的 5 个技巧 原创: 前端大全 前端大全 昨天 (给前端大全加星标,提升前端技能) 编译:伯乐在线/Mr.Dcheng http://blog.jobbole.com/11467 ...

  6. 浅谈mysql配置优化和sql语句优化【转】

    做优化,我在这里引用淘宝系统分析师蒋江伟的一句话:只有勇于承担,才能让人有勇气,有承担自己的错误的勇气.有承担错误的勇气,就有去做事得勇气.无论做什么事,只要是对的,就要去做,勇敢去做.出了错误,承担 ...

  7. Oracle性能优化之SQL语句

    1.SQL语句执行过程 1.1 SQL语句的执行步骤 1)语法分析,分析语句的语法是否符合规范,衡量语句中各表达式的意义. 2)语义分析,检查语句中涉及的所有数据库对象是否存在,且用户有相应的权限. ...

  8. 数据库性能优化之SQL语句优化

    一.问题的提出 在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的编写等是体会不出SQL语句各种写法的性能优劣,但是如果将应用系统提交实际应用后,随着数据库中数据的增加,系统 ...

  9. ORACLE性能优化之SQL语句优化

    版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[+]   操作环境:AIX +11g+PLSQL 包含以下内容: 1.  SQL语句执行过程 2.  优化器及执行计划 3.  合 ...

  10. SQL Server优化之SQL语句优化

    一切都是为了性能,一切都是为了业务 一.查询的逻辑执行顺序 (1) FROM left_table (3) join_type JOIN right_table (2) ON join_conditi ...

随机推荐

  1. servlet过滤器--使用过滤器统计网站访问人数的计数(注解形式)

    文章目录 1.什么是过滤器? 2.过滤器核心对象 3.过滤器创建和配置 4.举例子 1.什么是过滤器? 主要用于对客户端的请求进行过滤处理,再将经过过滤后的请求转交给下一个资源. 2.过滤器核心对象 ...

  2. Java I/O(4):AIO和NIO中的Selector

    您好,我是湘王,这是我的博客园,欢迎您来,欢迎您再来- 在Java NIO的三大核心中,除了Channel和Buffer,剩下的就是Selector了.有的地方叫它选择器,也有叫多路复用器的(比如Ne ...

  3. C++ Undefined Behavior 详细列表

    Undefined Behavior,即未定义的行为,指程序不可预测的执行效果,一般由错误的代码实现引起.出于效率.兼容性等多方面原因,语言标准不便于定义错误程序的明确行为,而是将其统称为" ...

  4. 驱动开发:内核枚举进程与线程ObCall回调

    在笔者上一篇文章<驱动开发:内核枚举Registry注册表回调>中我们通过特征码定位实现了对注册表回调的枚举,本篇文章LyShark将教大家如何枚举系统中的ProcessObCall进程回 ...

  5. Git 02: git管理码云代码仓库 + IDEA集成使用git

    Git项目搭建 创建工作目录与常用指令 工作目录(WorkSpace)一般就是你希望Git帮助你管理的文件夹,可以是你项目的目录,也可以是一个空目录,建议不要有中文. 日常使用只要记住下图6个命令: ...

  6. 二十四、PV与PVC介绍

    PV 与 PVC介绍 一.概念介绍 ​PersistentVolume (PV) 是由管理员设置的存储,它是群集的一部分.就像节点是集群中的资源一样,PV 也是集群中的资源. PV 是Volume 之 ...

  7. 【FAQ】关于华为地图服务定位存在偏差的原因及解决办法

    一. 问题描述: 华为地图服务"我的位置"能力,在中国大陆地区,向用户展示他们在地图上的当前位置与用户的实际位置存在较大的偏差. 具体差别可以查看下方的图片: 二. 偏差较大的原因 ...

  8. vue-项目的整体增删改查

    Dept: package com.example.demo.gs; public class Dept { private int id; private String name; private ...

  9. Vue 基础学习总结

    介绍 Vue.js 中文文档地址:https://cn.vuejs.org/guide/introduction.html#what-is-vue Vue.js 是什么 Vue (读音 /vjuː/, ...

  10. docker使用bind9实现域名解析

    目录 刷新服务 修改配置文件 从 114 缓存 查询 数据 可以 dig 无法 ping 查看 已经 区域 解析,并添加 新的 解析 项 在 linux 安装 局域网 cert rndc 查看 默认的 ...