⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 touyatoutiao.com/i6847406631983153672 「聚IT」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

场景:当我们接收到一些数据需要对其进行处理时,由于它们来自于不同的渠道(如:腾讯,头条),不同渠道所需的处理方式不同,下面我们写一个简单Demo来实现该的场景。

解决思路

1、首先构建一个 GeneralChannelRule 基础规则抽象类,定义一个抽象方法process(),不同的渠道都需要实现该抽象方法。

public abstract class GeneralChannelRule {
public abstract void process();
}

2、编写一个腾讯的规则类,定义具体对于腾讯渠道数据的处理逻辑

public class TencentChannelRule extends GeneralChannelRule
@Override
public void process() {
// Tencent处理逻辑
}
}

3、编写一个头条的规则类,定义具体对于头条数据的处理逻辑

public class TouTiaoChannelRule extends GeneralChannelRule
@Override
public void process() {
// TouTiao处理逻辑
}
}

4、建立一个简单的枚举类

public enum ChannelRuleEnum {
/**
* 头条
*/
TOUTIAO("TOUTIAO"),
/**
* 腾讯
*/
TENCENT("TENCENT"),
;
....
}

5、使用规则对数据进行处理。

public static void main(String[] args) {
//这里我们模拟接收到的数据,其渠道为为TOUTIAO,来自头条的数据
String sign = "TOUTIAO";
GeneralChannelRule rule;
//根据对应渠道获取对应的具体规则实现类
if (ChannelRuleEnum.TENCENT.code.equals(sign)) {
rule = new TencentChannelRule();
} else if (ChannelRuleEnum.TOUTIAO.code.equals(sign)) {
rule = new TouTiaoChannelRule();
} else {
//匹配不到
}
//执行
rule.process();
}

解析:如果通过上面的方式,则存在则两个缺点。

当我们需要新增新的渠道的时候,需要对main方法中的逻辑进行修改调整。这违背了设计模式中的开放封闭规则。开放封闭原bai则的核心的思想是软件实体是可扩du展,而不可zhi修改的。

也就是说,对扩展是开dao放的,而对修改是封闭的

新增渠道后,修改代码会产生大量的if else,不太优雅。为了解决以上的两个问题,我们可以借助枚举类来巧妙优化。

新的思路

1、下面我们调整一下枚举类,增加一个GeneralChannelRule属性,并且给对应渠道构建对应的GeneralChannelRule实现类,新增一个match() 匹配方法。

public enum ChannelRuleEnum {

/**
* 头条
*/
TOUTIAO("TOUTIAO",new TouTiaoChannelRule()),
/**
* 腾讯
*/
TENCENT("TENCENT",new TencentChannelRule()),
;

public String name;

public GeneralChannelRule channel;

ChannelRuleEnum(String name, GeneralChannelRule channel) {
this.name = name;
this.channel = channel;
}

//匹配
public static ChannelRuleEnum match(String name){
ChannelRuleEnum[] values = ChannelRuleEnum.values();
for (ChannelRuleEnum value : values) {
if(value.name.equals(name)){
return value;
}
}
return null;
}
public String getName() {
return name;
}

public GeneralChannelRule getChannel() {
return channel;
}
}

2、改写程序

public static void main(String[] args) {
String sign = "TOUTIAO";
ChannelRuleEnum channelRule = ChannelRuleEnum.match(sign);
GeneralChannelRule rule = channelRule.channel;
rule.process(sign);
}

解析:通过使用枚举类,在枚举中将 key 与 规则具体实现进行绑定。通过改变:

可以减少if -else使得代码更加优雅 如果需要新增渠道,我们只需要在编写具体规则实现类并继承GeneralChannelRule抽象类,并在枚举类中新增的枚举,而不需要改动到原先的任何代码。这符合了开发封闭原则。

最后

以上是通过枚举来巧妙干掉if-else的方案,对于减少 if-else 还有很多有趣的解决方案(如:状态设计模式等),感兴趣的朋友去查阅相关的资料。

文章目录
  1. 1. 解决思路
  2. 2. 新的思路
  3. 3. 最后