Eliminating If‑Else Chains with Enums and Abstract Classes in Java Channel Processing
This article demonstrates how to replace cumbersome if‑else statements with a clean, extensible design using an abstract rule class, concrete channel implementations, and an enum that binds channel identifiers to their processing logic, thereby adhering to the open‑closed principle.
When data arrives from multiple sources such as Tencent or Toutiao, each channel often requires its own processing logic, leading developers to write repetitive if‑else blocks. The article first presents a naive solution that defines an abstract GeneralChannelRule class and concrete subclasses for each channel, then uses a simple enum to identify the channel and a series of if‑else statements in main to select the appropriate rule.
public abstract class GeneralChannelRule {
public abstract void process();
} public class TencentChannelRule extends GeneralChannelRule {
@Override
public void process() {
// Tencent处理逻辑
}
} public class TouTiaoChannelRule extends GeneralChannelRule {
@Override
public void process() {
// TouTiao处理逻辑
}
} public enum ChannelRuleEnum {
TOUTIAO("TOUTIAO"),
TENCENT("TENCENT");
// ...
} public static void main(String[] args) {
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();
}The article points out two drawbacks of this approach: the need to modify the main method whenever a new channel is added, violating the open‑closed principle, and the proliferation of unwieldy if‑else chains.
To resolve these issues, the author refactors the enum to hold both the channel identifier and a ready‑made instance of the corresponding rule, and adds a static match method that returns the appropriate enum constant. This eliminates the conditional logic from the client code.
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) {
for (ChannelRuleEnum value : values()) {
if (value.name.equals(name)) {
return value;
}
}
return null;
}
} public static void main(String[] args) {
String sign = "TOUTIAO";
ChannelRuleEnum channelRule = ChannelRuleEnum.match(sign);
GeneralChannelRule rule = channelRule.channel;
rule.process();
}With this design, adding a new channel only requires creating a new rule class and adding a constant to the enum; no existing code needs to be altered, fully respecting the open‑closed principle. The article concludes by noting that similar reductions of if‑else can be achieved with other patterns such as the State pattern.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.