您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家?guī)碛嘘P如何實現(xiàn)在Java源代碼中的替換掉所以的if else,文章內容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
SmsSendService.java
public class SmsSendService{ /** * @Param phoneNo 手機號 * @Param content 短信內容 */ public void send(String phoneNo,String content){ //從配置中讀取 短信渠道 String channelType=config.getChannelType(); //如果是短信渠道A,則調用渠道A的api發(fā)送 if(Objects.equals(channelType,"CHANNEL_A")){ System.out.println("通過短信渠道A發(fā)送短信"); } //如果是短信渠道B,則調用渠道B的api發(fā)送 else if(Objects.equals(channelType,"CHANNEL_B")){ System.out.println("通過短信渠道B發(fā)送短信"); } } }
如果某天增加了一個短信渠道C,那么接著追加一個”else if…"
//... 此處省略部分代碼 ... //從配置中讀取 短信渠道 String channelType=config.getChannelType(); //如果是短信渠道A,則調用渠道A的api發(fā)送 if(Objects.equals(channelType,"CHANNEL_A")){ System.out.println("通過短信渠道A發(fā)送短信"); } //如果是短信渠道B,則調用渠道B的api發(fā)送 else if(Objects.equals(channelType,"CHANNEL_B")){ System.out.println("通過短信渠道B發(fā)送短信"); } //ADD: 如果是短信渠道C,則調用渠道C的api發(fā)送 else if(Objects.equals(channelType,"CHANNEL_C")){ System.out.println("通過短信渠道C發(fā)送短信"); } //... 此處省略部分代碼 ...
如果又加其他短信渠道了呢?你又寫一個“else if …" ?
顯然這種做法不可取,也不符合SOLID原則中的”開閉原則“ ——對擴展開放,對更改封閉。
這樣我們每次都需要修改原有代碼(對更改沒有封閉),不斷的添加”if else"。
接下來我們把代碼優(yōu)化一下:
優(yōu)化代碼1
定義一個短信渠道的接口 SmsChannelService,所有的短信渠道API都實現(xiàn)該接口;
短信渠道接口 SmsChannelService.java
public interface SmsChannelService{ //發(fā)送短信 void send(String phoneNo,String content); }
短信渠道A SmsChannelServiceImplA.java
public class SmsChannelServiceImplA implements SmsChannelService { public void send(String phoneNo, String content) { System.out.println("通過短信渠道A發(fā)送短信"); } }
短信渠道B SmsChannelServiceImplB.java
public class SmsChannelServiceImplB implements SmsChannelService { public void send(String phoneNo, String content) { System.out.println("通過短信渠道B發(fā)送短信"); } }
通過工廠類來初始化所有短信渠道service
SmsChannelFactory.java
public class SmsChannelFactory { private Map<String,SmsChannelService> serviceMap; //初始化工廠,將所有的短信渠道Service放入Map中 public SmsChannelFactory(){ //渠道類型為 key , 對應的服務類為value : serviceMap=new HashMap<String, SmsChannelService>(2); serviceMap.put("CHANNEL_A",new SmsChannelServiceImplA()); serviceMap.put("CHANNEL_B",new SmsChannelServiceImplB()); } //根據短信渠道類型獲得對應渠道的Service public SmsChannelService buildService(String channelType){ return serviceMap.get(channelType); } }
在原來的SmsSendService中調用不同短信渠道的接口。
原來的 SmsSendService 類優(yōu)化如下
public class SmsSendService { private SmsChannelFactory smsChannelFactory; public SmsSendService(){ smsChannelFactory=new SmsChannelFactory(); } public void send(String phoneNo,String content){ //從配置中讀取 短信渠道 String channelType=config.getChannelType(); //獲取渠道類型對應的服務類 SmsChannelService channelService=smsChannelFactory.buildService(channelType); //發(fā)送短信 channelService.send(phoneNo,content); } }
這樣SmsSendService類非常簡潔,把“if else"干掉了,
如果我要增加一個短信渠道C,無需再次更改 SmsSendService 類。
只需要增加一個類 SmsChannelServiceImplC 實現(xiàn) SmsChannelService 接口,
然后在工廠類 SmsChannelFactory 中增加一行初始化 SmsChannelServiceImplC 的代碼即可。
增加短信渠道C的實現(xiàn) SmsChannelServiceImplC.java
public class SmsChannelServiceImplC implements SmsChannelService { public void send(String phoneNo, String content) { System.out.println("通過短信渠道C發(fā)送短信"); } }
修改工廠類 SmsChannelFactory.java
public class SmsChannelFactory { private Map<String,SmsChannelService> serviceMap; //初始化 serviceMap ,將所有的短信渠道Service放入Map中 public SmsChannelFactory(){ //渠道類型為 key , 對應的服務類為value : serviceMap=new HashMap<String, SmsChannelService>(3); serviceMap.put("CHANNEL_A",new SmsChannelServiceImplA()); serviceMap.put("CHANNEL_B",new SmsChannelServiceImplB()); //ADD 增加一行 SmsChannelServiceImplC 的初始化代碼 serviceMap.put("CHANNEL_C",new SmsChannelServiceImplC()); } //根據渠道類型構建短信渠道Service public SmsChannelService buildService(String channelType){ return serviceMap.get(channelType); } }
“if else"是干掉了,但還是得修改原來的類 SmsChannelFactory ,不滿足"開閉原則",有沒有更好得方式呢?
我們通過使用spring的依賴注入進一步優(yōu)化代碼:
優(yōu)化代碼2
SmsChannelService 接口增加 getChannelType() 方法,這一步很關鍵。
public interface SmsChannelService { //發(fā)送短信 void send(String phoneNo,String content); //關鍵:增加getChannelType()方法,子類實現(xiàn)這個方法用于標識出渠道類型 String getChannelType(); }
子類增加該方法的實現(xiàn),并加上 @Service 注解,使其讓spring容器管理起來
SmsChannelServiceImplA.java
@Service public class SmsChannelServiceImplA implements SmsChannelService { public void send(String phoneNo, String content) { System.out.println("通過短信渠道A發(fā)送短信"); } //關鍵:增加 getChannelType() 實現(xiàn) public String getChannelType() { return "CHANNEL_A"; } }
SmsChannelServiceImplB.java
@Service public class SmsChannelServiceImplB implements SmsChannelService { public void send(String phoneNo, String content) { System.out.println("通過短信渠道B發(fā)送短信"); } //關鍵:增加 getChannelType() 實現(xiàn) public String getChannelType() { return "CHANNEL_B"; } }
修改 SmsChannelFactory 類: 這一步也很關鍵。
SmsChannelFactory.java
@Service public class SmsChannelFactory { private Map<String,SmsChannelService> serviceMap; /*注入:通過spring容器將所有實現(xiàn) SmsChannelService 接口的類的實例注入到 serviceList 中*/ @Autowired private List<SmsChannelService> serviceList; /*通過 @PostConstruct 注解,在 SmsChannelFactory 實例化后,來初始化 serviceMap */ @PostConstruct private void init(){ if(CollectionUtils.isEmpty(serviceList)){ return ; } serviceMap=new HashMap<String, SmsChannelService>(serviceList.size()); //將 serviceList 轉換為 serviceMap for (SmsChannelService channelService : serviceList) { String channelType=channelService.getChannelType(); //重復性校驗,避免不同實現(xiàn)類的 getChannelType() 方法返回同一個值。 if(serviceMap.get(channelType)!=null){ throw new RuntimeException("同一個短信渠道只能有一個實現(xiàn)類"); } /*渠道類型為 key , 對應的服務類為value : 與“優(yōu)化代碼1”中的通過手工設置“CHANNEL_A"、"CHANNEL_B"相比, 這種方式更加自動化,后續(xù)在增加“CHANNEL_C"無需再改此處代碼*/ serviceMap.put(channelType,channelService); } } //根據渠道類型獲取對應短信渠道的Service public SmsChannelService buildService(String channelType){ return serviceMap.get(channelType); } }
SmsSendService 加上 @Service 注解。通過 @Autowired 注入 SmsChannelFactory
SmsSendService.java
@Service public class SmsSendService { @Autowired private SmsChannelFactory smsChannelFactory; public void send(String phoneNo,String content){ //從配置中讀取短信渠道類型 String channelType=config.getChannelType(); //構建渠道類型對應的服務類 SmsChannelService channelService=smsChannelFactory.buildService(channelType); //發(fā)送短信 channelService.send(phoneNo,content); } }
這時,如果需要添加一個渠道C,那真的只需要添加一個 SmsChannelServiceImplC 即可,再也不用改原有代碼,完全遵循“開閉原則”。
SmsChannelServiceImplC.java
@Service public class SmsChannelServiceImplC implements SmsChannelService { public void send(String phoneNo, String content) { System.out.println("通過短信渠道C發(fā)送短信"); } public String getChannelType() { return "CHANNEL_C"; } }
上述就是小編為大家分享的如何實現(xiàn)在Java源代碼中的替換掉所以的if else了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業(yè)資訊頻道。
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。