by agate - Published: 2008-03-31 [6:00 下午] - Category: 历程
今天借到《JavaServer Faces in Action》一书,出于对事件模型的web开发的好奇心,让我读了此书第一章,里头有一个对 “组件” 这个名词的精妙阐述:
很遗憾,在当今的业界“组件”一词已经被过渡滥用了。操作系统是组件,应用程序是组件,EJB是组件,库是组件,甚至厨房的水槽也是。有大量的书籍论及组件,而那些优秀的书中则指出组件有多种定义。
如果你知道这个词的确切意义,那么你就不会对这个词的滥用感到奇怪。在词典中查找“组件(component)”这个词,将会看到他是要素(constituent)——整体的一部分——的同义词。因此,如果使用这个词的字面意思,那么在分布式应用的上下文中,操作系统确实是组件。
更有趣的是,从概念上讲,厨房水槽同操作系统相比与Faces组件更有共通之处。你无需自己从头制造它,只需要购买一个符合要求的水槽:尺寸、颜色、材料、容器数等。其他厨房用品也是如此,比如橱柜和工作台面。所有这些组件都有特定的接口,以使它们能够和其他东西集成,但是依赖于特定的环境设施(例如,下水管)。最终的结果可能是独特的,但整体是有独立可重用的部件组成的。
如果采用厨房组件的概念,并将其应用到软件上,会得出这样的定义:
---------定义--------
软件组件是具有特定的契约接口并且仅具有显示上下文(环境)依赖性的成分单元。软件组件可以独立部署,并且服从第三方的组成。
厨房的“上下文(环境)依赖性(context dependency)”是指诸如房间本身、配管、电路等因素。本质上,上下文是所有组件的容器,而容器这是拥有组件并且提供一系列允许进行组件操作的服务的系统。有时,这种操作在IDE中进行(设计时),有时在部署环境(比如JEE服务器)中运行(运行时)。
短语“独立部署”意味着组件是自包含的单元,可以安装到容器中。厨房水槽是独立的、自包含的组件,可以安装到工作台中。
当改造厨房时,雇佣一个承包商,由他来将你所选择的组件(橱柜、抽屉、水槽等)组装成一个完整的厨房。当用组件构建软件时,也是将各种组件组装起来,创建能够运行的软件系统。
是不是十分好理解,而且十分精辟啊!呵呵:水槽……
by agate - Published: 2008-03-27 [7:20 下午] - Category: 未分类
使用hibernate开发的朋友都知道,想在使用hibernate进行持久层操作的时候显示对应的sql语句,可以设置hibernate配置文件中的show_sql属性为true来实现这个需求。可是这个功能比较让人失望……他的语句是没错,但是参数值全是?这个带传入的参数符号,每个调试带来什么方便。
在这里,我介绍两个工具包来解决这个问题:[p6spy]和[sql_profiler],具体主页地址在下列给出
p6spy: http://www.p6spy.com
SQL Profile: http://www.jahia.net/jahia/page597.html
我们先来说说p6spy这个工具。在我理解上,他其实就是一个中间驱动,在数据库调用端和实际数据库驱动间做一个代理人的角色,进而加入了一些特有的辅助功能。在这里我们使用的调用端就是hibernate这个数据持久层框架,而数据库驱动我们用的是mysql的默认驱动(一般就是com.mysql.jdbc.Driver)。好,解释完理论开始实际试验:
* 将p6syp.zip(可能是tar文件包)下载好
* 将包中的p6syp.jar包放入你工程的classpath下(web项目就丢到WEB-INF/lib中)
* 将包中的spy.properties放入src目录中
* 修改hibernate配置文件中的数据库驱动为com.p6spy.engine.spy.P6SpyDriver这个中间驱动
* 修改刚才拷贝进src中的spy.properties文件,将realdriver的值设置成原来hibernate中的真正驱动(这里我是com.mysql.jdbc.Driver)

OK搞定!重新编译项目,以保证p6syp.jar和spy.properties编译进入目标地址。
接着就运行你的程序吧,看看控制台……(不要打我啊,我又没说控制台会有变化=.=)。但是看看你的工程根目录下是不是出现了spy.log,这里面就是你要的数据库操作历史,包括了真正传入的参数的具体值。
如果需要改变spy.log日志的生成地址,可以对应设置spy.properties文件的logfile属性给出绝对地址。(logfile默认是spy.log可以加上路径比如logfile = c:\xxx\xxx.log)
好了,似乎hibernate的?参数问题解决了,但是我的好多朋友都抱怨:“怎么这个log格式这么难懂啊!看着好不爽啊!”的确!p6syp的日志格式让人确实分外头大,于是乎介绍个SQL Profile来帮帮痛苦的大众。
照惯例,介绍介绍理论知识。SQL Profiler是一个基于p6syp的一个辅助包,可以实现很多功能,比如根据你的query来帮你生成合适的索引功能。在这里我们使用它的GUI控制介面,说白了就是一个监听器,在你通过p6spy进行数据库操作时,他就会很清晰地跟踪并列出你的操作,比单单查看那个恶心的spy.log来得舒服!既然基于p6syp当然也要用到p6syp.jar这个包咯,只是必须使用我们下载到的sqlprofiler.zip中的spy.properties来替换原来的项目中的那个文件,因为这个文件是定制过的,所谓的监听器也是靠这个文件才起作用的。好,废话说多了毕竟会烦,来说说具体步骤:
* 将下载好的sqlprofiler.zip包中的 sqlprofiler.jar 和spy.properties两个文件解压出来
* 使用新的spy.properties文件替换工程中原来的那个文件
* 根据刚才添加p6syp的过程,修改 spy.properties 文件的参数
* 使用 java -jar sqlprofiler.jar 命令启动sqlprofiler的GUI介面
* 再次启动你的应用吧,看看是不是在进行数据持久层操作的时候sqlprofiler的GUI介面中便出现了对应的操作记录,很清晰的列了出来:

by agate - Published: 2008-03-21 [6:13 下午] - Category: 历程, 感想
两年半了,整整两年半了。从刚刚开始接触java到现在,我一直拼命地学习,从简单的基础语法,到各种包库的使用,乃至现在各种框架的使用,难道你还说我不懂java?在不少人眼中,似乎只有学会架构,才算是精通java了……
今天之前我也是这么认为的,灿烂地在同学面前炫耀着自己掌握的技术,自我膨胀地强调:“啊,瞧!我可以如此快速,如此完美地建立起一个应用!”但是,一个小小的image把我的思维打了一个耳光~
也在图书馆看到很多基础的java书籍,《java线程》、《Think in java》……很好笑的是我也“看过”,随意地当作工具书来查询,不懂了翻翻看看,解决了便不深入追究了。也对自己的学弟学妹谆谆教诲,说啊!这些书是多么地好啊(其实,是多么好查的工具书啊!)
今天,在我对自己的毕业设计进行安全部分开发的时候,无意间和老师谈起了常用图形验证码的功能模块。常用各种工具拼凑开发的我自然而然地询问是否有这种工具的jar包时,老师轻蔑地笑了笑,说道:不用这么麻烦啊,自己写一个小工具不就好了!说着,他打开了自己的一个工程目录,打开了一个生成随即验证码图片的Servlet文件,不长的几段AWT代码,轻易地生成了带干扰线、随机背景色的随机验证码图片。
要面子的我表面没什么反应,内心的只有骤然的惊愕……我根本不知道AWT可以生成图像~毫不客气地说,我对java的GUI完全是个门外汉,还自以为牛逼地用着IDE画出一个个窗口。我回到座位上就暗自发誓,一定要学好AWT,可是回头想想,那只是AWT啊!Core Java之所以是Core就是因为他是所有java应用的基础核心,想要说精通?把Core Java好好研究透吧!到那个时候不用你炫耀你的优秀框架架构实例,你的编程魅力已经从你的字里行间中自然地奔涌出来了!
安静,要耐得住寂寞。掌握你已经有的,用好你已经有的!Core Java,你敢说你会了吗?
by agate - Published: 2008-03-15 [9:09 上午] - Category: 程序编码
相信每位初学OOP的同学都知道在这面向对象的世界里比较两个对象的方法是使用Equals来实现,可是如何写一个比较完美的又代码量小的Equals函数呢?
还有就是在散列表的数据结构中,散列表自身的数据结构算法需要用到对象比较的方法HashCode,所以常常我们会听到“老者”对我们谆谆而训曰:重写Equals方法是必须的,可是别忘了重写HashCode哦!
HashCode和Equals这两个方法的渊源可谓不浅,在这里我通过简单的代码片段,展示一个目前常用的比较完美且代码量小的方法重写方式:
/**
* 这里我们假定改类的名字为Example
*/
@Override
public int hashCode() {
int result = 关键属性.hashCode();
//这里31其实可以由任何一个质素代替,用来保证hashcode的不重复
result = 31 * result;
//关键属性不止一个的话可以加上
//result = result + 关键属性2.hashCode() + ……;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Example other = (Example) obj;
//如果关键属性不止一个的话就多写几个判断
if (!关键属性.equals(other.关键属性)) {
return false;
}
return true;
}