使用模板模式处理获取参数判断
今天在写一个Servlet,需要从获取很多web.xml中定义的参数。一般我们都这么取:
/** * 模板参数处理内部抽象类 * * 实现三个方法:getParameter()----对单个参数的处理,并返回处理结果 * isTrueOrFalse()---对处理结果进行过虑,判断是否调用处理结果方法setParameter() * setParameter()----对getParameter()方法得到的结果进行处理 * 实现所以方法后,调用executeParameter()方法,对多个参数进行统一处理 * * @author HANNY.YI * * @param <I>传入的参数类型 * @param <O>处理后结果的类型 */public abstract class ParameterTemplate<I,O> {/** * 处理参数 * * @param name传入的参数 */public void executeParameter(I...name) {for (I n : name) {O param = this.getParameter(n);if (isTrueOrFalse(param)) {setParameter(n,param);}}}/** * 对参数的处理方法 * * @param name传入的参数 * @return返回处理结果 */public abstract O getParameter(I name);/** * 过虑处理结果 * * @param param处理结果 * @return 返回true或返回false */public abstract boolean isTrueOrFalse(O param);/** * 对结果的处理方法 * * @param name传入的参数 * @param param处理结果 */public abstract void setParameter(I name,O param);} 3 楼 funcreal 2010-01-29 如果param != null 是不是 param.length() >= 0一定成立呢? 4 楼 myyate 2010-01-29 funcreal 写道如果param != null 是不是 param.length() >= 0一定成立呢?难道还有param.length() < 0的情况?
最方便的应该是类似Spring的HttpServletBean的实现。 5 楼 mercyblitz 2010-03-14 简单的问题复杂化了,为什么不用javax.servlet.ServletConfig#getInitParameterNames(),解释成一个Map<String,String>,过度的面向对象会带来复杂度~ 6 楼 H_eaven 2010-03-15 做法非常好.
但还不至于上升到模式的高度吧. -_-!
这个仅仅是编写代码的良好习惯. 借用<<Refactoring>>中的名词,这是Extract Method手法.
相对上文的例子中.executeParameter()方法它的外在功能,表达我要设置一个参数值,实现过程我首先需要获取一个参数,然后检查这个参数是否非空,如果不为空,将值设置,如果为空则不做处理.
这个实现需要三步完成,第一步略过,第二步,我关心的是这个参数是否非空,但对于executeParameter这个方法来说,没必要知道检查非空性的实现过程,对于第三步,也是同样的道理,我只关心参数非空的话,就将值设置,而不在乎你是怎么设置的详细过程.
经过Extract Method之后带来的好处多多.1.清晰性,当读到executeParameter这个方法,我看方法头大概知道它做什么,看方法体也很快能清楚它是执行步骤,如果对每一步的实现方法更兴趣,我可以再去看其它两个方法isNotNullParam,setParameter的具体实现,注意:这里的阅读都是主动的,而不是被动的,我对你的实现过程感兴趣就去看,不感兴趣就可以不看,如果没有这种分离,不管你感不感觉兴趣你都得看,因为你不看你就不知道方法的完整执行过程. 当读到其它两个方法, 阅读流程开始重复.
2.重用性, isNotNullParam这个方法有很强的通用性.判断一个对象是否为null,基本和业务这种高层次的抽象无关,相反它是一个很低级的概念,而且程序当中的其它地方也会有对参数,变量的非空性检查操作.
3.同一抽象层次. 细化2里的讨论,"判断一个对象是否为null,基本和业务这种高层次的抽象无关,相反它是一个很低级的概念",也就是说isNotNullParam方法的实现不应该出现在这个类里,现再你已经使用Extract Method做了第一步,那么从重用的角度和一个类里的方法都应该在同一抽象水平上的角度,应该再使用Move Method将isNotNullParam移动一个工具类中,(说到同一抽象,它也符合单一职责的语义,不在同一抽象水平,引起它们变化的因素必然不同,而一个类的变化只应有一个原因所引起.)
过度设计,首先这是一个无法量化的概念.只能和其它相比之后才能得出它是否过度设计了.我们只能参照着一些目标去做,当然实现过程会增加一些复杂性,比如方法数量比重构之前多了,类的数量比重构之前多了,但是数量是问题吗?如果是过度设计了就是问题,如果还没有,那就是正常的. PS:好像现再还没有一些硬性规定说一个类里你最多只能写5个10方法的吧(呵呵!).
楼主的例子的确简单些,相对也有些过度了,但简单对于学习很好.
我也曾经见过极端的人.4000多行的代码写到一个方法里,实现了一个独立的功能.
这也是个人习惯吧,有人习惯把所有东西写到一起,也有人喜欢将它们整理整理,归归类, 这在现实生活中,你身边也应该都有这两种性格的人吧,或者是一个人在不同方面所表现的这两种特质(扯远了-_-!).
注:方法头标示着做什么,而方法体则是怎么做的具体实现过程. 7 楼 魔力猫咪 2010-03-15 实际上我这部分代码已经被我删除了。使用了apache的BeanUtil进行参数拷贝,代码简单了好多,但是代价是增加了jar包。