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