策略模式一般都是用來消除if...else這種結構的代碼,本篇記錄一下使用枚舉類的方式來解決此類問題, 這與傳統的策略模式還是有很大的不同的。
首先來舉個例子:
public void doNotify(String type) { if (type.equals("EMAIL")) { System.out.println("通過郵件通知"); } else if (type.equals("SMS")) { System.out.println("通過短信通知"); } else if (type.equals("WECHAT")) { System.out.println("通過微信通知"); } }
以上代碼不但有if...else...還有email, sms, weChat 這種不明所以的字符串,真的不好!
那我們怎么辦?通常會搞一個枚舉類來封裝type的類型
public enum NotifyType { EMEAIL, SMS, WECHAT }
然后上面的業務代碼就會變成下會這個樣兒、
public void doNotify(String type) { if (type.equals(NotifyType.EMEAIL)) { System.out.println("通過郵件通知"); } else if (type.equals(NotifyType.SMS)) { System.out.println("通過短信通知"); } else if (type.equals(NotifyType.WECHAT)) { System.out.println("通過微信通知"); } }
可是,即便這樣又有啥用呢?枚舉的功能也很簡單啊!
下面給出一種新的解決思路(網上看到的,非原創)
重新定義NotifyType這個枚舉類
public enum NotifyType { EMAIL("郵件", NotifyMechanismInterface.byEmail()), SMS("短信", NotifyMechanismInterface.bySms()), WECHAT("微信", NotifyMechanismInterface.byWeChat()); private String desc; private NotifyMechanismInterface notifyMechanism; NotifyType(String desc, NotifyMechanismInterface notifyMechanism) { this.desc = desc; this.notifyMechanism = notifyMechanism; } public String desc() { return desc; } public NotifyMechanismInterface notifyMechanism() { return notifyMechanism; } }
定義功能接口或抽象類NotifyMechanismInterface.java
public interface NotifyMechanismInterface { void doNotify(String msg); static NotifyMechanismInterface byEmail() { return new NotifyMechanismInterface() { @Override public void doNotify(String msg) { // todo 業務邏輯 System.out.println("通過郵件通知:" + msg); } }; } /** * 使用lambda表達式 * * @return */ static NotifyMechanismInterface bySms() { return (msg -> System.out.println("通過短信通知:" + msg)); } static NotifyMechanismInterface byWeChat() { return (msg -> System.out.println("通過微信通知:" + msg)); } }
然后再看看測試代碼,即業務調用方
public class NotifyService { public void doNotify(String type) { // if (type.equals(NotifyType.EMEAIL)) { // System.out.println("通過郵件通知"); // } else if (type.equals(NotifyType.SMS)) { // System.out.println("通過短信通知"); // } else if (type.equals(NotifyType.WECHAT)) { // System.out.println("通過微信通知"); // } NotifyType.valueOf(type).notifyMechanism().doNotify("放假了。。。。"); } public static void main(String[] args){ NotifyService notifyService = new NotifyService(); notifyService.doNotify("EMAIL"); notifyService.doNotify("SMS"); notifyService.doNotify("WECHAT"); System.out.println(NotifyType.valueOf("EMAIL")); } }
通過郵件通知:放假了。。。。
通過短信通知:放假了。。。。
通過微信通知:放假了。。。。
EMAIL
完美!
相比於傳統的策略模式,java類都要少很多了,看起來代碼簡潔了很多,也便於理解。 如果有新增的通知渠道,只需要在枚舉類NotifyType添加內容和在NotifyMechanismInterface接口添加具體實現即可,調用方完全不需要修改任何的代碼。