星期三, 十一月 12, 2003

关于Struts和Webwork2的比较。

比较内容 Struts WebWork2 Action 类 在Struts里面,每一个 Action Class都需要扩展org.apache.struts.action.Action;这个在Java编程中会引来一些问题,就是关于多种继承的问题 Webwork仅仅需要implement com.opensymphony.xwork.Action Interface,您也可以implement其它的interface来实现更多的功能,譬如:validate(验证),localware(国际化)等,当然 webwork2也提供了一个类ActionSupport 集成了以上功能。Developer可以根据需要实现不同的功能。 线程模型 Struts Actions必须是thread-safe方式,它仅仅允许一个实例去处理所有的请求。所以action用到的所有的资源都必须统一同步,这个就引起了线程安全的问题。 Webwork 2 actions每一个请求对应一个action,因此没有线程的安全问题。实际上Servlet 容器对应每一个请求会产生许多Object,这种一个请求产生许多object的例子没有证明对性能产生太多的影响。现在Web容器都是这么处理Servlet的。 Servlet的依赖 Struts处理一个Action时候必须要依赖ServletRequest and ServletResponse。所以这一层摆脱不了Server容器。而serveltRequest可能会被web层的Context使用。 Webwork2 每一个action不依赖任何层和任何容器。他们使用Request和response是通过ActionContext,所以这个对于逻辑层的分离是很重要的。 测试 因为Struts的每一个action都必须用到request和response所以都必须通过web层来进行测试。这就导致了许多测试struts都要通过web容器(尽管现在有许多测试方法cactus mock 等)。 Webwork的action能够通过赋予一定的属性。就可以执行。同时您可以使用一个mock的实例去测试,而不是通过启动web容器来进行测试。 FormBean Struts 需要一个FormBeans针对每一个Form。而使用DynaBeans实际上没有太大的意义。不能够很好的处理现有的模型。 Webwork 能够动态的收集web的数据然后在赋值给bean。同时它还能够使用FormBean模式。Webwork2还允许现有的ModelDrvien进行导入处理。能够处理它就像处理action自己的属性一样。 前端表达语言 Struts大部分使用的是JSTL EL(JSP2。0)去获得数据的。在Collection上面处理显得很弱。 Webwork前端可以使用JSTL同时也可以使用多种表现形式。譬如:velocity freemaker jspparer xml等等。Webwork2 利用ongl建立一个valuestack来搜集数据 类型的转换 Struts FormBeans把所有的数据都作为string类型。得到一个自己需要的类型然后展示给用户是很困难的。 Webwork2 数据都是转换成Java中的类型。这个根据Form的类型自动转换。然后操作这些bean十分方便。 对Action 执行前和后的处理 Struts处理action的时候是基于class的hierarchies,很难在action处理前和后进行操作。 Webwork2 允许您处理action可以通过interceptor,就是在每一个action处理前或者后进行其它操作。 验证处理 因为struts的FormBean的属性都被认为是string类型。许多类型的验证都要进行类型转换的处理。FormBean对一个验证链的处理显然不行。 而webwork2的验证采用的是interceptor设计模式。它的这种验证方式决定了它十分灵活。而且一个验证可以重复不断的使用仅仅需要一个XML文件的定义。实际上webwork2的验证是采用了xwork的验证框架。 Action的链的控制 Struts里面每一个action对应一个处理,如果一个action转向另外一个action就很困难了。 Webwork使用一个强大的DispatcherChain去处理这个action链。很方便的从一个处理到另外一个处理。

星期五, 九月 19, 2003

又有好东东发现了!

现在新闻系统紧张的开发中,在JDO中发现很令我郁闷的事情,其实也就是数据库的开环和闭环事物的问题。譬如两个用户同时对一个Object进行操作就会引起事物的异常。在JDOCentral上面有一篇文章关于JDO事物处理的东西 http://www.jdocentral.com/JDO_ExpertCorner_DavidEzzio_20030320.html ,这个观点和一本书<<实用J2EE设计模式编程指南>> 里面关于数据库的处理差不多。

记得我当初很抵制Struts就是因为他过多的依赖了web项目,进行开发测试都很困难。现在我发现了WebWork 2,感觉确实不错。他主要使用了Xwork,在webwork2里面调用xwork里面定义的对应处理,这个设计是我很需要的,他和Struts方便就在我们不用太多的专注在Web的处理上,编写测试代码变得很容易(尽管cactus能够胜任测试)。这个项目是由opensymphony公司开发的。在这个公司网站我还发现了一个好东东OSCache,一个cache的工具,我发现他用JSP tag来表示,使用起来非常容易,不像apache的JCS那样繁琐。

还有就是发现了一个前端显示的tag很爽,尤其是他的分页和表格处理上,而恰恰table的处理上面是web层开发的重点,不断的罗列许许多多的数据。

就软件的价值的评测,我对此很是头疼。我原来想从软件的价值评测中得到软件的开发周期,但是发现很困难,软件的不可预知的东西太多。这方面我还是需要时间来锤炼自己。
软件的开发模式方面我自己深有体会的很多。
现在软件行业的发展逐渐的转向了web方面的开发。其实说起web方面的开发实际上就是如下开发:表示层、逻辑层、数据层。就我个人而言我很喜欢您所说的水平模式。因为现在编程语言和编程模式的发展也在向这方面发展,按照模块来发展我个人认为是早期软件开发的模式。但是按照我所说的软件开发的模式的话,需要很好的协调。就三个层次我先抛砖:
一、表示层:
表示层是向客户展示自己的产品的最前端,无论您后台的逻辑和数据处做的再好没有一个好的前端显示也是徒劳。现在软件的表示层开发面临的问题是,美工和编程者之间总是存在这样那样的合作的问题。
问题1:美工没有考虑整个系统的控制,没有采取包含文件、统一控制等方式进行开发,而是不断的开发一些重复的页面。这样的页面拿给开发者之后很容易导致开发者出现大量重复代码的现象,可以说是引诱开发者误入繁琐开发误区。
问题2:当开发者发现美工做的东西不符合自己的逻辑要求时候,需要美工进行修改,而美工修改的过程可能破坏原来的已经插入的代码。

现在有很多的项目组织正在解决表示层的问题,其实全部都是基于MVC思想的。他们可以使得表示层和逻辑层能够最大限度的分开。其中有几个Framework比较突出:
1:Apache 的Struts http://jakarta.apache.org/struts/index.html
2:Opensymphoney的webwork http://www.opensymphony.com/webwork/
3:Apache 的velocity http://jakarta.apache.org/velocity/index.html
等等。
我个人认为作为公司要是想开发稳定的产品就需要有自己的Framework。其实这些Framework都是采用Servlet/taglib/jstl等技术,并不是特别复杂,能够让美工和开发者共同参入进来产生一个Framework,在以后的开发中开发起来会变得得心应手,当然这些需要时间。
二、数据层:
我把数据层提到逻辑层前面说是因为逻辑层是需要表示层和数据层才能工作的。现代数据库技术的发展日新月异了,现在大家的观点就是怎么让数据层和逻辑层分开,现在的开发人员不短需要写逻辑,还要不短的写一些数据库的处理,譬如关掉连接数据库,产生事物,插入数据库,事物提交,关闭数据库等等繁琐的代码。一个逻辑里面有很大一部分集中在数据库的处理中这么繁琐的代码,而且数据库的sql语句还需要不短的调试。使得开发者在相当大的时间内集中在sql语句的调试上,而不是集中在商业逻辑的开发中。 如果我们的数据层能够做的很好的话,就是开发者仅仅需要一点点代码就可以和数据库打交道,而且和数据库打交道是纯Java代码,而不是sql语句之类的。现在这方面已经出现了好几个产品用来实现这方面的东西。就技术的角度来讲主要有两种:
1:在Java编译之后的代码上面enhance一些字节码进去。这方面的典范就是Sun公司提出的JDO(Java Data Object http://java.sun.com/products/jdo/).的确Sun公司提出的这种方法很先进,他让开发者不关心数据库的连接,而仅仅是关注与商业逻辑。譬如插入一个记录可以如下操作:
PersistenceManagerFactory pmf=JDOHelper.getPersistenceManagerFactory();
PersistenceManager pm=pmf.getPersistenceManager();
Transaction trans=pm.currentTransaction();
TestBean tb=new TestBean();
tb.setXX("asdf");
tb.setXXX("asdfasdf");
pm.makePersistence(tb);
trans.commit();
pm.close();

就这样插入到了数据库中。里面没有见到一点点sql的代码,仅仅关心在商业逻辑上面。可惜的是sun公司给出的是接口和一个简单的实现,发展的还不是很完善,外国有几家公司在做这方面的技术实现:
LIBeLIS http://www.libelis.com
Hemisphere http://www.hemtech.co.za
Apache 的Obj http://db.apache.org/ojb
等等。

2:使用XML、Java Object进行映射。这方面的技术发展比JDO早,现在做的也比较成熟了。这方面的典范莫过于 castor(http://castor.exolab.org/) hibernate (http://www.hibernate.org) ,他们都是使用了XML文件做为映射,书写自己的API,来进行persistence。尤其是hibernate表现非常不错,现在他的性能无疑成为最佳,最近又被JBOSS应用服务器采纳作为他的EJB中的CMP的引擎。

session = sessionFactory.openSession();
transaction = session.beginTransaction();

Cat max = new Cat();
max.setName("Max");
max.setSex('M');
max.setWeight(8.1f);
session.save(max);

if (commit) {
transaction.commit();
} else {
// Don't commit the transaction, can be faster for read-only operations
transaction.rollback();
}
session.close();

上述代码展示了利用hibernate进行数据库的插入。

数据库技术在O/R Mapping上面发展很快,这也是很多开发者关注的,因为他可以使得开发者从繁琐的数据库处理中解放出来。进行商业逻辑的编辑。但是现在这个东西行业没有标准,仍然出在发展的阶段,我想这个地方肯定会成为数据库开发的热点。因为在J2ee中CMP实际上就是O/R Mapping的结果,我相信这方面的技术肯定会得到长足发展。

三、逻辑层

现在商业逻辑层实际上就是处理客户的需求,一个Client向Server发出一个request然后来得到一个response.繁琐的使用代码来获取客户端的信息。譬如用户输入一个int,我们要检查他时候为空,然后在检查时候是数字型,如果不是则要返回信息。这些繁琐的处理带来大量的代码的重复。现在在商业逻辑上面的框架也有一些,他们主要是结合表示层来的,这个需要大量的代码演示。


综上所述:我个人认为一个系统在良好的设计之后,然后结合几个框架,采用水平的开发模式,我认为最好不过了。我心目中的开发方式:

1:拿到项目之后,由几个设计者和开发者共同研究出来整个系统的构成,技术实施方案。
2:然后在分配人手进行整体框架的搭建。为后期开发提供一个接口。
3:然后在研究整个系统的逻辑,此时应该让美工和开发这共同参加,研究出一些技术上面和美工方面的难点。
4:根据难点,有几个人重点突破此难点。此时开发者和美工可以先抛开此难点进行先期开发。
5:难点攻破之后,写出详细文档,归公司技术文档。移交开发者使用,并进行辅助。
6:系统完成之后进行系统测试。
而开发者在每天的开发过程大概如下:
1:上午由协调者召开1刻钟的会议,确定今天完成的任务,以及人员的配备情况。
2:开发者在开发的时候应该先书写完整的测试。然后在开发(一个高级工程师说的〕。
2:开发者可以进行两两结对进行编程,共同讨论。书写可以完成通过上面编写测试代码的代码。
3:在下班前半小时,各个开发者必须提交到CVS。
4:然后由协调者和开发者共同进行系统的整合,测试,发现Bug,归入Bug区。
5:大家击掌下班了。

上面提到的开发模式,人员不见得必须某两个人必须配对,可以不断的轮换。这样的开发方式是高效的,而且大家互相直接肯定可以学到这样那样的知识。但是要求开发者要有良好的 敬业精神和按时完成可以完成的任务。


以上是我的个人观点,还有许多,我不知道怎么用言语来表达,我对软件的开发模式方面和服务器的一些原理方面很感兴趣。

今天终于在sourceforge上从build到deploy完成了。中间经历了许多挫折。好在我不气馁。
cvs.sourceforge.net 存放project文件
shell.sourceforge.net 用来进行文件中转以及pulblish站点。
cf.sourceforge.net 用来build工程文件。
上面都没有ftp。只有shell.sourceforge.net使用了psftp,所以大部分的文件传输都采用了scp来操作,感觉scp功能真的挺强大的。 因为shell.sourceforge.net限制了用户的权限,只好使用cf.sourceforge.net.但是cf却不能访问其他机器资源,只能访问shell的资源,所以shell充当了swap的角色。
呵呵,感觉maven的site:sshdeploy确实不错呀。 一次从编译到build到deploy. 爽就一个字。
中间最郁闷的就是cf不能访问外部资源,当然也包括了http://www.ibiblio.org上面的资源,所以。。。。。:mad: 只好把本机的所有maven的包通过psftp上传到shell,然后在通过scp下载到cf上面。真是疯狂郁闷。还好,今天的网速不错。 该松一口气了。

好累,好累,中间还用了 sourceforge的开源管理。 现在所有的项目都集中在 http://acai.ejb.cn 上面,可以在线查看源码。 今天太晚了,还没有向CVS提交东东。

星期五, 九月 05, 2003

研究了一些项目管理方面的知识.

  最近两天一直在研究管理方面的东西,发现项目管理方面的东西太多了,我的头都弄大了,发现XML的功能简直穿插在各个系统之间,我现在在项目中间使用了maven,把以前的项目都集合在一起.感觉maven的功能很强,不过现在发现apache的forrest不怎么使用了,maven正在蓬勃发展.在sourceforge站点许多都采用了maven.而且还发现maven能够支持eclipse工程,在sourceforge站点还有一个eclipse的 maven plugin .
   其实maven的安装很简单,不过我还是倒腾了半天,主要是因为maven的官方网站上面的参考资料是maven beta-8的,后来发现它的简单和ant差不多,主要是建立 project.xml 以及 maven.xml project.properties文件,但是功能比ant强大了许多.在使用xdoc的时候修改site.jsl,而所有的网站数据都是以xml的格式存放.就可以产生不同风格的站点.真的很不错.现在我的开发采用了eclipse+maven+cvs+ant+junit...呵呵,感觉很爽.

新闻系统的代码经过了美化和优化,书写了详细了的doc,整个系统包含下面几个

  • Front View Control
    采用mvc设计,用来控制系统的访问.
  • Java Common Utility
    包含了一些常用的java包,有JDO,Jibx等常用的处理.
  • Luence Serach System
    Apache的搜索引擎,主要是扩展了XML的搜索功能,针对XML的搜索设计.
  • News System API
    新闻系统的一些API函数,包含了JDO/jibx的处理.

  这两天南京的天气不错,昨天晚上看电视国奥队点球击败了乌拉圭,应用sina的一句话评论:比西亚裁判还黑的裁判.周末来了,球赛又有的看了.最近一周在看天天周星驰很是过瘾.周六去阿姨家大吃一顿,周日在玄武湖公园休闲一把.

星期三, 九月 03, 2003

今天天气非常好。

天气好,心情好,今天终于搞定了lucene,把他捏合在新闻系统里面搜索XML文档,参考了IBM DW上面的一篇文章。

陆姐姐被别人请走了,今天晚上只有何妹妹照顾我了。

luncene这个东西发现面向对象的功能非常强大,看看他的查找功能就知道他的设计精湛,title:"The Right Way" AND text:go 当初我在o/r mapping中很想实现这样的复杂的查找功能。在建立索引的时候这个表格应该是很重要的:

方法 切词 索引 存储 用途
Field.Text(String name, String value) Yes Yes Yes 切分词索引并存储,比如:标题,内容字段
Field.Text(String name, Reader value) Yes Yes No 切分词索引不存储,比如:META信息,
不用于返回显示,但需要进行检索内容
Field.Keyword(String name, String value) No Yes Yes 不切分索引并存储,比如:日期字段
Field.UnIndexed(String name, String value) No No Yes 不索引,只存储,比如:文件路径
Field.UnStored(String name, String value) Yes Yes No 只全文索引,不存储
在建立索引的 时候更新起来很困难。按照offical上面的解释是先删除建立就是update,^_^.而且删除不是很方便,我这里的删除感觉很市别扭:
public static void deleteDocument(String indexPath, String keyId)
        throws LuceneException {
        IndexReader reader = null;

        try {
            reader = IndexReader.open(indexPath);

            for (int i = 0; i < reader.numDocs(); i++) {
                if (reader.isDeleted(i)) {
                    continue;
                }

                Document doc = reader.document(i);

                if (doc.get("objectId").equals(keyId)) {
                    reader.delete(i);

                    break;
                }
            }
        } catch (IOException e) {
            throw new LuceneException(e.getMessage(), e);
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
    }
不过还好。现在基本上完成了对XML文档的搜索功能,下列函数主要是对XML的索引建立起重要作用。
public static void indexDocs(IndexWriter writer, File file)
        throws ParserConfigurationException, SAXException, IOException {
        if (file.isDirectory()) {
            String[] files = file.list();

            for (int i = 0; i < files.length; i++)
                indexDocs(writer, new File(file, files[i]));
        } else {
            System.out.println("adding " + file);

            XMLDocumentHandlerSAX hdlr = new XMLDocumentHandlerSAX(file);
            writer.addDocument(hdlr.getDocument());

            // For DOM, use
            // XMLDocumentHandlerDOM hdlr = new XMLDocumentHandlerDOM();
            // writer.addDocument(hdlr.createXMLDocument(file));
        }
    }
通过修改XMLDocumentHandlerSAX类来实现自己需要的Index. 查找功能:
public static void search(String indexPath, String keyWords) throws LuceneException {
        Searcher searcher = null;

        try {
            searcher = new IndexSearcher(indexPath);

            Analyzer analyzer = new StandardAnalyzer();

            Query query = QueryParser.parse("title:\"" + keyWords + "\"  " +
                    keyWords, "content", analyzer);
            System.out.println("Searching for: " + query.toString());

            Hits hits = searcher.search(query);
            System.out.println(hits.length() + " total matching documents");

            final int HITS_PER_PAGE = 10;

            for (int start = 0; start < hits.length();
                    start += HITS_PER_PAGE) {
                int end = Math.min(hits.length(), start + HITS_PER_PAGE);

                for (int i = start; i < end; i++) {
                    Document doc = hits.doc(i);
                    String name = doc.get("objectId");
                    System.out.println(name);
                    System.out.println(doc.get("author"));
                    System.out.println(doc.get("title"));
                }
            }

           
        } catch (IOException e) {
            throw new LuceneException(e.getMessage(),e);
        } catch (ParseException e) {
			throw new LuceneException(e.getMessage(),e);
		}finally{
			if(searcher!=null){
				try {
					searcher.close();
				} catch (IOException e1) {
				}
			}
		}
    }
几个参考资源 下午要和整个新闻捏合在一块咯。

今天给销售人员讲解域名的知识,自己也好好学习了一下域名的知识。域名的MX/A/CNAME/URL/等等,感觉自己也学习了许多。尤其是自己认识了一个DOS下面的域名工具:nslookup。这个工具我感觉确实很强大的。自己也发现了许多资源。

其实我的感觉就是域名这个东西就是有了一些功能的机器的名字,而这些功能和Domain Name Server密切相关。

今天中午把自己的站点加了一些功能,可以看看右边的天气预报哟,实时体现了南京的天气。还加了一个google的搜索bar. hoho,研究lucene了。

最近的新闻系统中要用到搜索功能。发现lucene功能很强大。研究了半天才略知道他的工作的原理。阿菜落伍了,现在有几个产品好像用到这个东东.

已经有很多Java项目都使用了Lucene作为其后台的全文索引引擎,比较著名的有:



  • Jive:WEB论坛系统;

  • Eyebrows:邮件列表HTML归档/浏览/查询系统,优秀论文“TheLucene
    search engine: Powerful, flexible, and free
    ”作者就是EyeBrows系统的主要开发者之一,而EyeBrows已经成为目前APACHE项目的主要邮件列表归档系统。

  • Cocoon:基于XML的web发布框架,全文检索部分使用了Lucene

  • Eclipse:基于Java的开放开发平台,帮助部分的全文索引使用了Lucene


还有就是cjsmile的新闻也用到了这个东东。

下面有几个资源感觉很不错

星期一, 九月 01, 2003

今天公司开会了。

今天公司开会了,讨论了好多东西,呵呵,感觉很好哟。 晚上回到家,我又收到了我的生日礼物一个playboy的钱包。感觉自己好幸福耶。

阿菜来到南京工作了,顺便记录了阿菜的生活情况。也来当一会博客,当初编码设为utf-8,发现好多人的浏览器在浏览的时候出现了空白,其实就是浏览器编码的问题,只好改为gb2312的了。
阿菜最近在开发一系列产品,用到了一些新兴的技术。jdo/jibx/o-r mapping/xml/xslt等等,有好多阿菜还是一知半解,不过阿菜会努力工作的.