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