策略模式之枚舉


策略模式一般都是用來消除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接口添加具體實現即可,調用方完全不需要修改任何的代碼。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM