zoukankan      html  css  js  c++  java
  • 策略模式之枚举

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

  • 相关阅读:
    mock数据
    关于适配各种浏览器的图片预览。
    闭包
    兼容性 适配
    递归 使用callee
    webservice的model层命名空间不同的问题
    删除右键菜单中的Git
    windows server core 设置shell 及切换
    设置共享用户名密码
    Windows Remote Shell(WinRM)使用介绍
  • 原文地址:https://www.cnblogs.com/z-qinfeng/p/12314942.html
Copyright © 2011-2022 走看看