CTO寫的代碼,真是絕了!
最近我看到某廠的 CTO 寫的代碼,被全網(wǎng)吐槽,我們一起來欣賞一下!
本文通過一個簡單的例子來展示如何通過枚舉巧妙地干掉 if-else,使代碼看起來更佳優(yōu)雅。
場景:當(dāng)我們接收到一些數(shù)據(jù)需要對其進行處理時,由于它們來自于不同的渠道(如:騰訊,頭條),不同渠道所需的處理方式不同,下面我們寫一個簡單 Demo 來實現(xiàn)該的場景。
解決思路
①首先構(gòu)建一個 GeneralChannelRule 基礎(chǔ)規(guī)則抽象類,定義一個抽象方法process(),不同的渠道都需要實現(xiàn)該抽象方法。
- public abstract class GeneralChannelRule {
- public abstract void process();
- }
②編寫一個騰訊的規(guī)則類,定義具體對于騰訊渠道數(shù)據(jù)的處理邏輯。
代碼如下:
- public class TencentChannelRule extends GeneralChannelRule
- @Override
- public void process() {
- // Tencent處理邏輯
- }
- }
③編寫一個頭條的規(guī)則類,定義具體對于頭條數(shù)據(jù)的處理邏輯。
代碼如下:
- public class TouTiaoChannelRule extends GeneralChannelRule
- @Override
- public void process() {
- // TouTiao處理邏輯
- }
- }
④建立一個簡單的枚舉類。
代碼如下:
- public enum ChannelRuleEnum {
- /**
- * 頭條
- */
- TOUTIAO("TOUTIAO"),
- /**
- * 騰訊
- */
- TENCENT("TENCENT"),
- ;
- ....
- }
⑤使用規(guī)則對數(shù)據(jù)進行處理。
代碼如下:
- public static void main(String[] args) {
- //這里我們模擬接收到的數(shù)據(jù),其渠道為為TOUTIAO,來自頭條的數(shù)據(jù)
- String sign = "TOUTIAO";
- GeneralChannelRule rule;
- //根據(jù)對應(yīng)渠道獲取對應(yīng)的具體規(guī)則實現(xiàn)類
- if (ChannelRuleEnum.TENCENT.code.equals(sign)) {
- rule = new TencentChannelRule();
- } else if (ChannelRuleEnum.TOUTIAO.code.equals(sign)) {
- rule = new TouTiaoChannelRule();
- } else {
- //匹配不到
- }
- //執(zhí)行
- rule.process();
- }
解析:如果通過上面的方式,則存在則兩個缺點。
a.當(dāng)我們需要新增新的渠道的時候,需要對 main 方法中的邏輯進行修改調(diào)整。
這違背了設(shè)計模式中的開放封閉規(guī)則。開放封閉原則的核心的思想是軟件實體是可擴展,而不可修改的。也就是說,對擴展是開放的,而對修改是封閉的。
b.新增渠道后,修改代碼會產(chǎn)生大量的 if else,不太優(yōu)雅。
為了解決以上的兩個問題,我們可以借助枚舉類來巧妙優(yōu)化。
新的思路
①下面我們調(diào)整一下枚舉類,增加一個 GeneralChannelRule 屬性,并且給對應(yīng)渠道構(gòu)建對應(yīng)的 GeneralChannelRule 實現(xiàn)類,新增一個 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;
- }
- }
②改寫程序,代碼如下:
- public static void main(String[] args) {
- String sign = "TOUTIAO";
- ChannelRuleEnum channelRule = ChannelRuleEnum.match(sign);
- GeneralChannelRule rule = channelRule.channel;
- rule.process(sign);
- }
解析:通過使用枚舉類,在枚舉中將 key 與規(guī)則具體實現(xiàn)進行綁定。
通過改變:
- 可以減少 if-else 使得代碼更加優(yōu)雅。
- 如果需要新增渠道,我們只需要在編寫具體規(guī)則實現(xiàn)類并繼承 GeneralChannelRule 抽象類,并在枚舉類中新增的枚舉,而不需要改動到原先的任何代碼。這符合了開發(fā)封閉原則。
最后
以上是通過枚舉來巧妙干掉 if-else 的方案,對于減少 if-else 還有很多有趣的解決方案(如:狀態(tài)設(shè)計模式等),感興趣的朋友去查閱相關(guān)的資料。
作者:聚 IT
編輯:陶家龍
出處:toutiao.com/i6847406631983153672