`
魔力猫咪
  • 浏览: 105740 次
  • 来自: 北京
社区版块
存档分类
最新评论

使用模板模式处理获取参数判断

阅读更多
今天在写一个Servlet,需要从获取很多web.xml中定义的参数。一般我们都这么取:
String param = getInitParameter("参数名");
//然后必须判断一下是否Null
if (param != null && param.length() >= 0) {
//处理参数
......
}

但是一个两个还好,参数太多的话就看到一大堆这种代码。感觉特别别扭。所以就想到了模板的方式,反正都是先取出来,然后判断,最后处理。处理这部分抽象出来,其他部分作为模板。
一个内部的模板类如下:
    /**
     * 模板参数处理内部抽象类
     * @author Miao
     * @version 0.2
     * @since 0.2
     */
    private abstract class ParameterTemplate {

        /**
         * 判断参数是否为Null
         * @param param 参数
         * @return 参数非Null返回true,参数为Null返回false
         * @since 0.2
         */
        private boolean isNotNullParam(String param) {
            if (param == null || param.length() == 0) {
                return false;
            } else {
                return true;
            }
        }

        /**
         * 处理参数
         * @param name 参数名
         * @since 0.2
         */
        public void executeParameter(String name) {
            String param = getInitParameter(name);
            if (isNotNullParam(param)) {
                setParameter(param);
            }
        }

        /**
         * 设置参数
         * @param param 参数
         * @since 0.2
         */
        public abstract void setParameter(String param);
    }

setParameter方法是抽象方法,用于在判断完成后处理参数。
然后读取参数就可以像下面这样:
new ParameterTemplate() {

            @Override
            public void setParameter(String param) {
                //处理参数
                ......
            }
        }.executeParameter("参数名");



我现在正在考虑是否应该把获取参数部分也抽象出来,这样这个类就可以用在其他地方了,而不是局限于Servlet中。正在继续重构中。
不知道自己改得是简化了处理还是复杂了处理,大家也讨论讨论。
分享到:
评论
7 楼 魔力猫咪 2010-03-15  
实际上我这部分代码已经被我删除了。使用了apache的BeanUtil进行参数拷贝,代码简单了好多,但是代价是增加了jar包。
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多行的代码写到一个方法里,实现了一个独立的功能.
   这也是个人习惯吧,有人习惯把所有东西写到一起,也有人喜欢将它们整理整理,归归类, 这在现实生活中,你身边也应该都有这两种性格的人吧,或者是一个人在不同方面所表现的这两种特质(扯远了-_-!).
注:方法头标示着做什么,而方法体则是怎么做的具体实现过程.
5 楼 mercyblitz 2010-03-14  
简单的问题复杂化了,为什么不用javax.servlet.ServletConfig#getInitParameterNames(),解释成一个Map<String,String>,过度的面向对象会带来复杂度~
4 楼 myyate 2010-01-29  
funcreal 写道
如果param != null 是不是 param.length() >= 0一定成立呢?

难道还有param.length() < 0的情况?
最方便的应该是类似Spring的HttpServletBean的实现。
3 楼 funcreal 2010-01-29  
如果param != null 是不是 param.length() >= 0一定成立呢?
2 楼 hanny.yi 2010-01-29  
在楼主的基础上改的,多指教

/**
 * 模板参数处理内部抽象类
 * 
 * 实现三个方法:	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);
}
1 楼 xiaoyi3317 2010-01-19  
嗯。。是可以这样的。。写的不错

相关推荐

    设计模式 GOF 23

    实际上,当我评估一个面向对象系统的质量时,所使用的方法之一就是要判断系统的设计者是否强调了对象之间的公共协同关系。在系统开发阶段强调这种机制的优势在于,它能使所生成的系统体系结构更加精巧、简洁和易于...

    设计模式:可复用面向对象软件的基础--详细书签版

    实际上,当我评估一个面向对象系统的质量时,所使用的方法之一就是要判断系统的设计者是否强调了对象之间的公共协同关系。在系统开发阶段强调这种机制的优势在于,它能使所生成的系统体系结构更加精巧、简洁和易于...

    Excel VBA实用技巧大全 附书源码

    01008获取模板保存的默认路径 01009获取库文件夹的路径 01010获取路径分隔符 01011获取Excel主窗口标题栏的名称 01012获取Excel窗口的状态(大小) 01013获取Excel主窗口的高度和宽度 01014获取Excel主窗口的左边界...

    精通AngularJS part1

    使用ng—include处理多个UI区域183 不支持嵌套路由184 65路由相关的模式及技巧185 处理链接185 创建可点击的链接186 兼容HTML5及hashbang模式186 链接外部页面187 组织路由定义187 将路由定义分离到多个模块...

    asp.net知识库

    在ASP.NET页面中推荐使用覆写(Override)而不是事件处理(Event Handler) 常用编码工具类,支持base64,md5,des,crc32 也谈谈技术面试 在C#里把ArrayList转换为Array 或 把Array转换为ArrayList C# 2.0 在.NET 2.0中...

    机器人对话常用语模板-聊天机器人的技术原理和未来的发展.pdf

    机器⼈对话常⽤语模板_聊天机器⼈的技术原理和未来的发展 近年来,⼈⼯智能越来越⽕,那你们真的知道⼈⼯智能吗? ⼀、⼈⼯智能是什么 ⼀、⼈⼯智能是什么 ⼈⼯智能(Artificial Intelligence),英⽂缩写为AI。它是...

    PHP开发实战1200例(第1卷).(清华出版.潘凯华.刘中华).part1

    实例047 使用条件运算符判断数字的奇偶性 78 实例048 判断用户是否具有后台管理权限 79 实例049 打印随机组合生日祝福语 80 实例050 打印2000~2020年的所有闰年 81 实例051 前置运算符和后置运算符的区别 82 实例052...

    Visual C++ 2005入门经典.part08.rar (整理并添加所有书签)

    Visual C++ 2005入门经典.pdf(整理并添加所有书签) ...22.4 在无约束模式中使用DataGridView控件 22.5 定制DataGridView控件 22.5.1 定制题头单元格 22.5.2 定制非题头单元格 22.5.3 动态设置单元格样式...

    PHP开发实战1200例(第1卷).(清华出版.潘凯华.刘中华).part2

    实例047 使用条件运算符判断数字的奇偶性 78 实例048 判断用户是否具有后台管理权限 79 实例049 打印随机组合生日祝福语 80 实例050 打印2000~2020年的所有闰年 81 实例051 前置运算符和后置运算符的区别 82 实例052...

    Visual C++ 2005入门经典.part04.rar (整理并添加所有书签)

    Visual C++ 2005入门经典.pdf(整理并添加所有书签) ...22.4 在无约束模式中使用DataGridView控件 22.5 定制DataGridView控件 22.5.1 定制题头单元格 22.5.2 定制非题头单元格 22.5.3 动态设置单元格样式...

    Visual C++ 2005入门经典.part07.rar (整理并添加所有书签)

    Visual C++ 2005入门经典.pdf(整理并添加所有书签) ...22.4 在无约束模式中使用DataGridView控件 22.5 定制DataGridView控件 22.5.1 定制题头单元格 22.5.2 定制非题头单元格 22.5.3 动态设置单元格样式...

    Visual C++ 2005入门经典.part09.rar (整理并添加所有书签)

    Visual C++ 2005入门经典.pdf(整理并添加所有书签) ...22.4 在无约束模式中使用DataGridView控件 22.5 定制DataGridView控件 22.5.1 定制题头单元格 22.5.2 定制非题头单元格 22.5.3 动态设置单元格样式...

    Visual C++ 2005入门经典.part06.rar (整理并添加所有书签)

    Visual C++ 2005入门经典.pdf(整理并添加所有书签) ...22.4 在无约束模式中使用DataGridView控件 22.5 定制DataGridView控件 22.5.1 定制题头单元格 22.5.2 定制非题头单元格 22.5.3 动态设置单元格样式...

    Visual C++ 2005入门经典.part05.rar (整理并添加所有书签)

    Visual C++ 2005入门经典.pdf(整理并添加所有书签) ...22.4 在无约束模式中使用DataGridView控件 22.5 定制DataGridView控件 22.5.1 定制题头单元格 22.5.2 定制非题头单元格 22.5.3 动态设置单元格样式...

    php网络开发完全手册

    5.6.2 实例类型的判断方法instanceof 78 5.6.3 对象的克隆 78 5.7 一些设计观念 80 5.7.1 策略模式(Strategy Pattern) 81 5.7.2 单例模式(Singleton Pattern) 81 5.7.3 工厂模式(Factory Pattern) 83 5.8 接口...

    API之网络函数---整理网络函数及功能

    lopen 以二进制模式打开指定的文件 lread 将文件中的数据读入内存缓冲区 lwrite 将数据从内存缓冲区写入一个文件 LZClose 关闭由LZOpenFile 或 LZInit函数打开的一个文件 LZCopy 复制一个文件 LZInit 这个函数...

Global site tag (gtag.js) - Google Analytics