- 浏览: 308404 次
- 性别:
- 来自: 成都
文章分类
- 全部博客 (187)
- JAVA (66)
- JS (2)
- AJAX (9)
- Servlet (5)
- eclipse (4)
- html (2)
- PL/SQL (9)
- SOAP (1)
- other (14)
- JavaScript (8)
- Struts2 (6)
- Spring (10)
- Hibernate (5)
- JSP (1)
- Linux (3)
- WebService (2)
- 数据结构 (1)
- DB (5)
- English (1)
- maven (4)
- Code standard (2)
- SQL (1)
- 软件架构 (1)
- Tomcat (2)
- windows (1)
- HSQL (0)
- Open source framework (0)
- Web (6)
- Compass (0)
- Flex (1)
- OSGI (1)
- python (3)
- groovy (2)
- JPA (2)
- svn (1)
- jetty (1)
最新评论
-
zjfshowtime:
it doesn't work !why
Tomcat 和 Jetty 下 JNDI 配置 DBCP 连接池 -
coco5012:
Useful
sql server日期时间函数 datetime -
烟花弥散:
弱弱的问一句,您的第一个举例中else 后面可以跟判断条件吗? ...
Java高手论道:你还在用if else吗? -
coco5012:
Not very simple
使用assembly plugin实现自定义打包 -
mqlfly2008:
[color=red][size=medium][size=x ...
Java高手论道:你还在用if else吗?
面向过程设计和面向对象设计的主要区别是:是否在业务逻辑层使用冗长的if else判断。如果你还在大量使用if else,当然,界面表现层除外,即使你使用Java/C#这样完全面向对象的语言,也只能说明你的思维停留在传统的面向过程语言上。
传统思维习惯分析
为什么会业务逻辑层使用if else,其实使用者的目的也是为了重用,但是这是面向过程编程的重用,程序员只看到代码重用,因为他看到if else几种情况下大部分代码都是重复的,只有个别不同,因此使用if else可以避免重复代码,并且认为这是模板Template模式。
他范的错误是:程序员只从代码运行顺序这个方向来看待它的代码,这种思维类似水管或串行电路,水沿着水管流动(代码运行次序),当遇到几个分管(子管),就分到这几个分管子在流动,这里就相当于碰到代码的if else处了。
而使用OO,则首先打破这个代码由上向下顺序等同于运行时的先后循序这个规律,代码结构不由执行循序决定,由什么决定呢?由OO设计;设计模式会取代这些if else,但是最后总是由一个Service等总类按照运行顺序组装这些OO模块,只有一处,这处可包含事务,一般就是Service,EJB中是Session bean。
一旦需求变化,我们更多的可能是Service中各个OO模块,甚至是只改动Service中的OO模块执行顺序就能符合需求。
这里我们也看到OO分离的思路,将以前过程语言的一个Main函数彻底分解,将运行顺序与代码其他逻辑分离开来,而不是象面向过程那样混乱在一起。所以有人感慨,OO也是要顺序的,这是肯定的,关键是运行顺序要单独分离出来。
是否有if else可以看出你有没有将运行顺序分离到家。
设计模式的切入口
经常有人反映,设计模式是不错,但是我很难用到,其实如果你使用if else来写代码时(除显示控制以外),就是在写业务逻辑,只不过使用简单的判断语句来作为现实情况的替代者。
还是以大家熟悉的论坛帖子为例子,如ForumMessage是一个模型,但是实际中帖子分两种性质:主题贴(第一个根贴)和回帖(回以前帖子的帖子),这里有一个朴素的解决方案:
建立一个ForumMessage,然后在ForumMessage加入isTopic这样判断语句,注意,你这里一个简单属性的判断引入,可能导致你的程序其他地方到处存在if else 的判断。
如果我们改用另外一种分析实现思路,以对象化概念看待,实际中有主题贴和回帖,就是两种对象,但是这两种对象大部分是一致的,因此,我将ForumMessage设为表达主题贴;然后创建一个继承ForumMessage的子类ForumMessageReply作为回帖,这样,我在程序地方,如Service中,我已经确定这个Model是回帖了,我就直接下溯为ForumMessageReply即可,这个有点类似向Collection放入对象和取出时的强制类型转换。通过这个手段我消灭了以后程序中if else的判断语句出现可能。
从这里体现了,如果分析方向错误,也会导致误用模式。
讨论设计模式举例,不能没有业务上下文场景的案例,否则无法决定是否该用模式,下面举两个对比的例子:
第一.举例的第一个代码案例是没有上下文的,文中只说明有一段代码:
main() { if(case A){ //do with strategy A }else(case B){ //do with strategy B }else(case C){ //do with strategy C } } |
这段代码只是纯粹的代码,没有业务功能,所以,在这种情况下,我们就很难确定使用什么模式,就是一定用策略模式等,也逃不过还是使用if else的命运,设计模式不是魔法,不能将一段毫无意义的代码变得简单了,只能将其体现的业务功能更加容易可拓展了。
第二.在一个PacketParser业务案例,这段代码是体现业务功能的,是一个数据包的分析,作者也比较了各种模式使用的不同,所以我们还是使用动态代理模式或Command模式来消灭那些可能存在的if else
由以上两个案例表明:业务逻辑是我们使用设计模式的切入点,而在分解业务逻辑时,我们习惯则可能使用if else来实现,当你有这种企图或者已经实现代码了,那么就应该考虑是否需要重构Refactoring了。
if else替代者
那么实战中,哪些设计模式可以替代if else呢?其实GoF设计模式都可以用来替代if else,我们分别描述如下:
当数据对象存在各种可能性的状态,而且这种状态将会影响到不同业务结果时,那么我们就应该考虑是否使用状态模式,当然,使用状态模式之前,你必须首先有内存状态这个概念,而不是数据库概念,因为在传统的面向过程的/面向数据库的系统中,你很难发现状态的,从数据库中读取某个值,然后根据这个值进行代码运行分流,这是很多初学者常干的事情。
使用传统语言思维的情况还有:使用一个类整数变量标识状态:
public class Order{ private int status; //说明: //status=1 表示订货但为查看 ; //status=2 表示已经查看未处理; //status=3 表示已经处理未付款 //status=4 表示已经付款未发货 //status=5 表示已经发货 } |
上述类设计,无疑是将类作为传统语言的函数来使用,这样导致程序代码中存在大量的if else。
当你面临几种算法或者公式选择时,可以考虑策略模式,传统过程语言情况是:从数据库中读取算法数值,数值1表示策略1,例如保存到数据库;数值为2表示策略2,例如保存到XMl文件中。这里使用if else作为策略选择的开关。
传统过程的思维情况是:如果客户端发出代号是1或"A",那么我调用A.java这个对象来处理;如果代号是2或"B",我就调用B.java来处理,通过if else来判断客户端发送过来的代码,然后按事先约定的对应表,调用相应的类来处理。
MVC模式的传统语言误用和Command模式类似,在一个Action类中,使用if else进行前后台调度,如果客户端传送什么命令;我就调用后台什么结果;如果后台处理什么结构,再决定推什么页面,不过,现在我们使用Struts/JSF这样MVC模式的框架实现者就不必范这种低级错误。
职责链模式和Command模式是可选的,如果你实在不知道客户端会发出什么代号;也没有一个事先定义好的对照表,那么你只能编写一个个类去碰运气一样打开这个包看一下就可以。与Command是不同在AOP vs Decorator一文中有分析。
代理对象可以是符合某种条件的代表者,比如,权限检验,传统面向过程思维是:当一个用户登陆后,访问某资源时,使用if else进行判断,只有某种条件符合时,才能允许访问,这样权限判断和业务数据逻辑混乱在一起,使用代理模式可以清晰分离,如果嫌不太好,使用动态代理,或者下面AOP等方式。
其实使用filter过滤器也可以替代我们业务中的if else,过滤器起到一种过滤和筛选作用,将符合本过滤器条件的对象拦截下来做某件事情,这就是一个过滤器的功能,多个过滤器组合在一起实际就是if else的组合。
所以,如果你实在想不出什么办法,可以使用过滤器,将过滤器看成防火墙就比较好理解,当客户端有一个请求时,经过不同性质的防火墙,这个防火墙是拦截端口的;那个防火墙是安全检查拦截等等。过滤器也如同红蓝白各种光滤镜;红色滤镜只能将通过光线中的红色拦截了;蓝色滤镜将光线中的蓝色拦截下来,这实际上是对光线使用if else进行分解。
如图,通过一个个条件过滤器我们立体地实现了对信号的分离,如果你使用if else,说明你是将图中的条件1/2/3/4合并在一起,在同一个地方实现条件判断。
OO设计的总结
还有一种伪模式,虽然使用了状态等模式,但是在模式内部实质还是使用if else或switch进行状态切换或重要条件判断,那么无疑说明还需要进一步努力。更重要的是,不能以模式自居,而且出书示人。
真正掌握面向对象这些思想是一件困难的事情,目前有各种属于揪着自己头发向上拔的解说,都是误人子弟的,所以我觉得初学者读Thinking in Java(Java编程思想)是没有用,它试图从语言层次来讲OO编程思想,非常失败,作为语言参考书可以,但是作为Java体现的OO思想的学习资料,就错了。
OO编程思想是一种方法论,方法论如果没有应用比较,是无法体会这个方法论的特点的,禅是古代一个方法论,悟禅是靠挑水砍柴这些应用才能体会。
那么OO思想靠什么应用能够体会到了?是GoF设计模式,GoF设计模式是等于软件人员的挑水砍柴等基本活,所以,如果一个程序员连基本活都不会,他何以自居OO程序员?从事OO专业设计编程这个工作,如果不掌握设计模式基本功,就象一个做和尚的人不愿意挑水砍柴,他何以立足这个行业?早就被师傅赶下山。
最后总结:将if else用在小地方还可以,如简单的数值判断;但是如果按照你的传统习惯思维,在实现业务功能时也使用if else,那么说明你的思维可能需要重塑,你的编程经验越丰富,传统过程思维模式就容易根深蒂固,想靠自己改变很困难;建议接受专业头脑风暴培训。
用一句话总结:如果你做了不少系统,很久没有使用if else了,那么说明你可能真正进入OO设计的境地了。(这是本人自己发明的实战性的衡量考核标准)。
评论
如果下面这样写是不是合理些 ?
main() {
if(case A){
//do with strategy A
}else if (case B){
//do with strategy B
}else {
//do with strategy C
}
}
发表评论
-
JAVA ArrayList深层 拷贝 克隆
2012-04-23 14:13 2557大家应该理解浅拷贝和深拷贝的区别: 浅拷贝:被复制对象的任何 ... -
深入 Lucene 索引机制
2011-09-21 21:49 615简介: Lucene 是一个 ... -
Apache DBUtils使用总结
2011-09-19 10:50 980Apache DBUtils使用总结 DBU ... -
Java搜索引擎 Lucene
2011-09-19 10:43 881Lucene 是一套用于全文 ... -
Java的弱引用(Weak Reference)
2011-09-16 08:47 1324之前一直没有接触 ... -
JAVA读取大文件
2011-09-13 10:27 3398/** * */ package com.b2s. ... -
Java性能优化技巧
2011-09-06 11:59 890摘要: ==================== ... -
java程序性能优化
2011-09-06 11:58 694一、避免在循环条件中使用复杂表达式 在不做编译优化 ... -
大家在普遍认识中对架构师这一职业有哪些误区
2011-09-04 10:26 745误区一 架构师与项目经理没有区别。大家经常在 ... -
Ibatis执行SQL操作把SQL打印到控制台
2011-08-10 10:46 2771要想让Ibatis打印SQL语句到控制台,可以在log4j.x ... -
用 PMD 铲除 bug
2011-06-08 17:33 1031简介: PMD 是一个开源的静态分析工具,是一个值得您添加 ... -
Web Service 实现分布式服务的基本原理
2011-05-24 13:27 1496简单的说, 就是客户端 ... -
Web Service概述
2011-05-24 10:16 1006Web Service是构建互联网 ... -
有关母亲的名人名言
2011-05-09 08:42 810God could not be everywhere and ... -
装饰器模式[Decorator]
2011-05-06 17:42 730装饰器模式 主要应用于这样一种场合,当你已经 ... -
Java 7已经完成的七大新功能预览
2011-05-06 12:26 1144今年的Devoxx大会又是一次有关Java 7进程的一 ... -
回归测试
2011-05-04 17:16 795回归测试, 英文是Regression testing。 ... -
jxl 使用总结收藏
2011-04-29 17:33 964jxl的一些总结 要 ... -
Struts1下如何实现国际化
2011-04-25 14:18 1139Struts1下如何实现国际化 1.ApplicationR ... -
JAVA静态导入(import static)详解
2011-04-20 17:52 4023在Java 5中,import语句得到了增强,以便提供甚至更加 ...
相关推荐
- 安全性考虑要求严格的电池管理政策和技术规范,确保电池在使用过程中的可靠性。 7. 电池寿命与经济效益: - 换电模式可能导致电池过度使用,缩短电池的整体使用寿命,从而影响经济效益。 - 电池寿命的缩短可能...
这篇文章是一位90后的女性IT从业者对IT行业的观察和思考,主要讨论了技术工作者在职场中的地位和出路。她指出,IT行业中存在着一种普遍的看法,即技术开发者被看作是“代码民工”,随着年龄的增长,他们可能会面临更...
在压缩包文件中,包含了多个部分或章节的压缩文件,如6.zip至7.zip,这些可能代表着书中的不同章节或者案例研究,方便读者分段下载和阅读。 首先,HTML5的关键改进在于其增强了语义化标签,如`<header>`、`<footer>...
这个系统由多个Java类组成,包括`Menu.java`、`display.java`、`search.java`、`add.java`和`delete.java`,每个类负责不同的功能。 系统的核心是管理一个名为`records`的文本文件,其中包含了Adfaith Consulting...
书中的源码可能包括了这些元素的实例,展示了如何创建响应式的布局、如何利用`<form>`元素的新的输入类型提高表单验证,以及如何使用Web Storage(包括localStorage和sessionStorage)进行本地数据存储。此外,HTML5...
《***-国泰君安-房地产行业地产论道系列之生存篇(十):生存法则,立新篇》这份文件是一份关于房地产行业发展趋势的分析报告,由国泰君安出具,并对地产行业的未来生存策略提出了新的见解。 报告导读提到杠杆逐步...
【房地产行业地产论道系列之保障性租赁住房篇(十五):新一轮的实物形成周期】 在当前的房地产行业中,保障性租赁住房成为了政策关注的新焦点。这篇报告详细分析了保障性租赁住房对于整个行业以及中国经济转型的...
这份“2021中期投资策略集锦:论道(29页)”是一份深入研究各类行业投资趋势的研究报告,旨在为投资者提供中期投资决策的参考。以下是对报告中涉及的主要行业和策略的详细解读: 1. **宏观:回归与变革** 报告...
EVA模型不仅能反映公司当前的净资产价值,还能综合考虑预测的超额收益,而且可以将其拆分为当前、中期和远期三段,为房地产企业提供更为合理的估值。在远期估值方面,由于房地产行业的开发业务缺乏明显的竞争壁垒,...
在商用车联网方面,其商业价值甚至超过了乘用车。尽管与国际水平起点差不多,但我国在政策支持和市场潜力方面表现出色,有巨大的发展潜力。 华为等企业也将车联网视为M2M战略的重要投入方向之一,并愿意与其他产业...
报告还列出了重点覆盖的公司及其评级情况,涵盖了国内和海外的多家知名房地产企业。这些公司的评级涵盖了不同的细分行业,包括房地产开发和房地产经营两大领域。投资者可以根据自身的需求和偏好,参考这些评级来进行...
当前零售行业的数字化转型已经成为企业发展的关键所在,尤其是在面临着新冠疫情这种前所未有的挑战下,技术强度和数字化能力的高低直接关系到企业的生存和发展。本文通过分析零售企业数字化转型的挑战与机遇,旨在为...
中国地产行业在过去的20年间,经历了以城镇化和工业化为主导的发展阶段,这期间房地产行业的杠杆作用显著,城市化率的提升带动了农民大量进城,而政府和房地产企业成为了这一进程中的主导力量。随着资本的积累和土地...
房地产行业地产论道系列之信用篇(八):历史的真相-0414-国泰君安-23页.pdf
【产品方法论】是产品经理在实践中形成的系统理论,它涵盖了产品经理如何理解世界、设计产品以及应对各种挑战的方式。产品方法论不仅关注产品的具体操作,更注重于高层次的思考和策略制定,是产品经验的提炼和升华。...
【标题】"陈幼坚--竹叶青北京论道馆完整竣工图.zip"是一个压缩文件,其中包含了由著名设计师陈幼坚设计的竹叶青北京论道馆的竣工图纸。陈幼坚是国际知名的设计大师,他的作品通常融合了东西方文化的精髓,展现出独特...
在2021年的云栖大会上,德勤中国强调了企业数字化转型的四个关键趋势。首先,【技术驱动战略】成为核心,企业不再仅依赖数字化技术作为辅助工具,而是将其融入核心战略,通过自动化、人工智能等先进技术来制定和执行...