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

    时态 什么是时态? 英语的时态,是由动作的时间 + 动作的状态:这俩一起构成了时态 动词的时间和状态在一起,合称时态 理论上的十六种时态 先将 时间和状态的概念搞清楚,再具体讨论,用什么词,去构成时态 ...

  2. 【Serverless】快速集成云函数HarmonyOS

    ​1.学习目标 什么是AppGallery Connect云函数 云函数是一项Serverless计算服务,提供FaaS(Function as a Service)能力,可以帮助开发者大幅简化应用开 ...

  3. C# Static关键词的使用

    一.C#中类的方法分为静态方法和非静态方法 静态方法有Static关键词修饰 静态方法归类所有,而非静态方法归类的实例所有:静态方法无需类去实例化可直接调用 静态成员属于类所有,为各个类的实例所公用, ...

  4. Linux系统命令基础

    Linux系统命令基础 前面咱们已经成功安装了Linux系统--centos7,那么现在奔向Linux命令行的世界. Linux命令格式 1.一般情况下,[参数]是可选的,一些情况下[文件或路径]也是 ...

  5. Python学习之实例1

    一.求n个数字的平均值 n=3 #定义常量n=3 sum=0 #定义求和变量sum count=0 #定义变量count,记录输入数字的次数 print("请输入3个数字:") # ...

  6. Vue3 企业级优雅实战 - 组件库框架 - 3 搭建组件库开发环境

    前文已经初始化了 workspace-root,从本文开始就需要依次搭建组件库.example.文档.cli.本文内容是搭建 组件库的开发环境. 1 packages 目录 前面在项目根目录下创建了 ...

  7. Node.js的学习(二)node.js 模块化

    一.Node.js模块化 1.模块化概要 早期的javascript版本没有块级作用域.没有类.没有包.也没有模块,这样会带来一些问题,如复用.依赖.冲突.代码组织混乱等,随着前端的膨胀,模块化显得非 ...

  8. 2022春每日一题:Day 33

    题目:[USACO 6.1.3] Cow XOR 没找到这题具体网址,这个题就是求最大异或区间(总长度尽量小,右端点尽量大) 嗯很显然一个[l,r]的异或和=s[r]s[l-1],那么现在有了优秀的n ...

  9. Spring MVC文件请求处理详解:MultipartResolver

    org.springframework.web.multipart.MultipartResolver是Spring-Web针对RFC1867实现的多文件上传解决策略. 1 使用场景 前端上传文件时, ...

  10. JDK中内嵌JS引擎介绍及使用

    原文: JDK中内嵌JS引擎介绍及使用 - Stars-One的杂货小窝 最近研究阅读这个APP,其主要功能就是通过一个个书源,从而实现移动端阅读的体验 比如说某些在线小说阅读网站,会加上相应的广告, ...