場景:當咱們接收到一些數據須要對其進行處理時,因爲它們來自於不一樣的渠道(如:騰訊,頭條),不一樣渠道所需的處理方式不一樣,下面咱們寫一個簡單Demo來實現該的場景。設計模式
一、首先構建一個 GeneralChannelRule 基礎規則抽象類,定義一個抽象方法process(),不一樣的渠道都須要實現該抽象方法。ide
`public abstract class GeneralChannelRule {` `public abstract void process();` `}`
二、編寫一個騰訊的規則類,定義具體對於騰訊渠道數據的處理邏輯優化
`public class TencentChannelRule extends GeneralChannelRule` `@Override` `public void process() {` `// Tencent處理邏輯` `}` `}`
三、編寫一個頭條的規則類,定義具體對於頭條數據的處理邏輯this
`public class TouTiaoChannelRule extends GeneralChannelRule` `@Override` `public void process() {` `// TouTiao處理邏輯` `}` `}`
四、創建一個簡單的枚舉類spa
`public enum ChannelRuleEnum {` `/**` `* 頭條` `*/` `TOUTIAO("TOUTIAO"),` `/**` `* 騰訊` `*/` `TENCENT("TENCENT"),` `;` `....` `}`
五、使用規則對數據進行處理。設計
`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();` `}`
解析:若是經過上面的方式,則存在則兩個缺點。code
當咱們須要新增新的渠道的時候,須要對main方法中的邏輯進行修改調整。這違背了設計模式中的開放封閉規則。開放封閉原bai則的核心的思想是軟件實體是可擴du展,而不可zhi修改的。繼承
也就是說,對擴展是開dao放的,而對修改是封閉的開發
新增渠道後,修改代碼會產生大量的if else,不太優雅。爲了解決以上的兩個問題,咱們能夠藉助枚舉類來巧妙優化。get
一、下面咱們調整一下枚舉類,增長一個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;` `}` `}`
二、改寫程序
`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 還有不少有趣的解決方案(如:狀態設計模式等),感興趣的朋友去查閱相關的資料。