`
hyxw5890
  • 浏览: 35296 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

利用Java枚举实现策略模式

阅读更多
    我们在使用Java的枚举时往往会结合Switch来进行判断以实现不同值的处理,但是我们知道多用switch不是一种很好的代码风格,不利用维护和适应变化,因为这不符合开-闭原则。为此一种方法是用策略模式来重构原有的枚举实现,但是很多时候确实需要用枚举的方法来实现,如一周的天数等等,这也是JDK5.0重新引入枚举的原因。Joshua Bloch在Effective Java(第二版)里提出了一种枚举策略模式 很好的解决了这个问题。

    要说明问题最好的办法就是结合例子,比如我们要定义一年的12个月,往往会想到枚举,假设我们要定义一个返回某年某个月的天数的方法,我们知道一个月一般是30,31天,其中2月比较特殊,闰年是28天,其他年份是29天,如果单纯用swtich的话显然不是一种很好的代码风格,这个例子还好,因为我们知道一年12月不会变,但有的枚举可能在今后添加新的类型,这样我们就不得不去修改原有的switch了,明显不符合开--闭原则,影响维护并且容易引入Bug。

    这时我们可以利用嵌套枚举和接口结合的方法来实现开闭原则的思想。

   
    public enum Year {
	JAN(MonType.BIG), FEB(MonType.SPECIAL), MAR(MonType.BIG), APR(MonType.SMALL), MAY(
			MonType.BIG), JUN(MonType.SMALL),//剩余月份略掉;
	Year(MonType type) {
		this.type = type;
	}
	private final MonType type;
    public int ContainDays(int year) {
       return type.countResult(year);
	}
	private enum MonType implements Count {
		BIG {
			public int countResult(int num) {
				return 31;
			}
		},
		SMALL {
			public int countResult(int num) {
				return 30;
			}
		},
		SPECIAL {
			public int countResult(int num) {
				if ((num % 4 == 0 && num % 100 != 0) || (num % 400 == 0)) {
                       return 28;
				} else {
					return 29;
				}				
			}
		}
	}
}

    

  public interface Count {
	public int countResult(int num);
}


在上面这段代码里Year枚举的ContainDays方法返回某年某月的天数,因为大月,小月,闰年和非闰年的2月返回的天数都是不一样的,也就是根据输入参数计算的策略可能不一样,这种情况下我们应抽象出接口来适应这种变化,但是要是直接在Year枚举里12月的类型实例一一实现该接口就会带来很多重复代码(代码有臭味了),因为像1,3,5等都是返回31天的,也就是计算方法一样,而如用嵌套枚举(相当于内部类),外层枚举把处理方法委托给了内部枚举,让内部枚举(代表每个月计算天数的不同类型)来具体实现Count接口(用来返回每月天数),则很好的消除了冗余代码,并且今后要是添加其他处理类型,只需再次实现Count接口,原有的代码无需改变,很好的实现了开闭原则。

5
0
分享到:
评论
1 楼 xyfwjk 2012-10-23  
很好,很不错,学习了

相关推荐

    Java利用策略模式优化过多if else代码

    主要介绍了Java利用策略模式优化过多if else代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

    rmiscout:RMIScout使用单词列表和蛮力策略来枚举Java RMI函数并利用RMI参数解组漏洞

    它支持多种Java RMI协议,方法调用和利用。 功能概述 支持多种类型的Java RMI服务器: RMI-JRMP(又称纯RMI;通常为端口1099):远程对象注册表服务(rmiregistry) IIOP要求使用JRE 1.8。由于在以后的运行时中已...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

     21.4.1 利用数据库系统的独占锁来实现悲观锁  21.4.2 由应用程序实现悲观锁  21.5 利用Hibernate的版本控制来实现乐观锁  21.5.1 使用元素  21.5.2 使用元素  21.5.3 对游离对象进行版本检查  21.5.4 强制...

    超级有影响力霸气的Java面试题大全文档

    但通常情况下,由于Java Bean是被容器所创建(如Tomcat)的,所以Java Bean应具有一个无参的构造器,另外,通常Java Bean还要实现Serializable接口用于实现Bean的持久性。Java Bean实际上相当于微软COM模型中的本地...

    java 面试题 总结

    但通常情况下,由于Java Bean是被容器所创建(如Tomcat)的,所以Java Bean应具有一个无参的构造器,另外,通常Java Bean还要实现Serializable接口用于实现Bean的持久性。Java Bean实际上相当于微软COM模型中的本地...

    Java并发编程(学习笔记).xmind

    是一个枚举,表示 keepAliveTime 的单位(有NANOSECONDS, MICROSECONDS, MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS,7个可选值 线程的创建与销毁 管理队列任务 饱和策略 AbortPolicy ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part4

     21.4.1 利用数据库系统的独占锁来实现悲观锁  21.4.2 由应用程序实现悲观锁  21.5 利用Hibernate的版本控制来实现乐观锁  21.5.1 使用元素  21.5.2 使用元素  21.5.3 对游离对象进行版本检查  21.5.4 强制...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part3

     21.4.1 利用数据库系统的独占锁来实现悲观锁  21.4.2 由应用程序实现悲观锁  21.5 利用Hibernate的版本控制来实现乐观锁  21.5.1 使用元素  21.5.2 使用元素  21.5.3 对游离对象进行版本检查  21.5.4 强制...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part1.rar

     21.4.1 利用数据库系统的独占锁来实现悲观锁  21.4.2 由应用程序实现悲观锁  21.5 利用Hibernate的版本控制来实现乐观锁  21.5.1 使用元素  21.5.2 使用元素  21.5.3 对游离对象进行版本检查  21.5.4 强制...

    Java开发实战1200例(第1卷).(清华出版.李钟尉.陈丹丹).part3

    实例117 策略模式的简单应用 148 实例118 适配器模式的简单应用 149 实例119 普通内部类的简单应用 151 实例120 局部内部类的简单应用 152 实例121 匿名内部类的简单应用 153 实例122 静态内部类的简单应用 154 第2...

    Java开发技术大全 电子版

    12.3.2指定一个保留策略380 12.3.3使用反射在运行时获得注释380 12.3.4AnnotatedElement接口383 12.3.5使用默认值383 12.3.6标记注释384 12.3.7单成员注释385 12.3.8内置注释386 12.3.9使用注释的一些限制390...

    SQL注入攻击与防御(安全技术经典译丛)

     4.6 枚举数据库模式  4.6.1 SQL Server  4.6.2 MySQL  4.6.3 Oracle  4.7 提升权限  4.7.1 SQL Server  4.7.2 Oracle  4.8 窃取哈希口令  4.8.1 SQL Server  4.8.2 MySQL  4.8.3 Oracle  ...

    Hibernate实战(第2版 中文高清版)

     16.4.1 利用有状态的bean实现会话   16.4.2 利用EJB编写DAO   16.4.3 利用依赖注入   16.5 测试   16.5.1 理解不同种类的测试   16.5.2 TestNG简介   16.5.3 测试持久层   16.5.4 考虑性能基准   ...

    asp.net知识库

    利用自定义属性,定义枚举值的详细文本 Web标准和ASP.NET - 第一部分 XHTML介绍 在ASP.NET页面中推荐使用覆写(Override)而不是事件处理(Event Handler) 常用编码工具类,支持base64,md5,des,crc32 也谈谈技术面试...

    SQL注入攻击与防御

    4.6 枚举数据库模式 131 4.6.1 SQL Server 131 4.6.2 MySQL 136 4.6.3 Oracle 139 4.7 提升权限 142 4.7.1 SQL Server 142 4.7.2 Oracle 147 4.8 窃取哈希口令 148 4.8.1 SQL Server 149 4.8.2 MySQL 150 4.8.3 ...

Global site tag (gtag.js) - Google Analytics