写代码的时候经常遇到这样的场景:根据某个字段值来进行不同的逻辑处理。例如,不同的会员等级在购物时有不同的折扣力度。如果会员的等级很多,那么代码中与之相关的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. File常用的方法操作、在磁盘上创建File、获取指定目录下的所有文件、File文件的重命名、将数据写入File文件

    文章目录 1.基本介绍 2.构造方法 3.常用的方法 4.代码实例 4.1 创建文件和目录(目录不存在) 4.1.1 代码 4.1.2 测试结果 4.2 测试目录存在的情况.直接写绝对的路径名 4.2 ...

  2. Chrony时间同步服务

    概:  网络时间协议(Network Time Protocol,NTP)是用于网络时间同步的协议.提供NTP时间同步服务的软件有很多,这里采用Chrony软件来实现时间同步 chrony 的优势:  ...

  3. JavaScript函数式编程之函子

    函子(Functor) 函子是一个特殊的容器,通过一个普通对象来实现,该对象具有map方法,map方法可以运行一个函数对值进行处理(变形关系),容器包含值和值变形关系(这个变形关系就是函数).函数式编 ...

  4. flutter 系列之:flutter 中的幽灵offstage

    目录 简介 Offstage详解 Offstage的使用 总结 简介 我们在使用flutter的过程中,有时候需要控制某些组件是否展示,一种方法是将这个组件从render tree中删除,这样这个组件 ...

  5. .net 温故知新:【8】.NET 中的配置从xml转向json

    一.配置概述 在.net framework平台中我们常见的也是最熟悉的就是.config文件作为配置,控制台桌面程序是App.config,Web就是web.config,里面的配置格式为xml格式 ...

  6. 高性能MySQL(第4版) 第一章 MySQL架构 读书笔记

    这本书去年11月出的,今年中文版也出了,并且直接上了微信读书,之后有空就读一读,分享下读书笔记~ 原文内容比较充实,建议有时间可以读一下原文. 第一章主要是个概览. MySQL的逻辑架构 默认情况下, ...

  7. SpringBoot 01: JavaConfig + @ImportResource + @PropertyResource

    springboot的前置知识:通过注解创建对象和读取配置文件 1. JavaConfig 设计思想 使用java类作为xml配置文件的替代,是配置spring容器的纯java的方式 可以创建java ...

  8. MAUI新生-XAML语法基础:语法入门Element&Property&Event&Command

    一.XAML(MAUI的XAML)和HTML 两者相似,都是标签语言(也叫标记)组成的树形文档.每个标签元素,可视为一个对象,通过"键=值"形式的标签属性(Attribute),为 ...

  9. Stream流使用

    Stream流的使用 转换为流的操作 map转换为stream流 Map map = new HashMap(); Set<Map.Entry<String,Integer>> ...

  10. 更换K8S证书可用期

    帮助文档:https://zealous-cricket-cfa.notion.site/kubeadm-k8s-24611be9607c4b3193012de58860535e 解决: 1.安装GO ...