策略模式之枚举

策略模式一般都是用来消除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接口添加具体实现即可,调用方完全不需要修改任何的代码。

猜你喜欢

转载自www.cnblogs.com/z-qinfeng/p/12314942.html
今日推荐