A mind for learning english in our project

    English is very important now.I have a mind of learning english,that is two words:use it!It's told me by a friend in the LearnDiary Developing Group(LDDG).And this friend introduce a english learning method-"study english reverse method" invented by generals Zhong DaoLong.This method can be downloaded at this address:,It's need pdf reader with Simpfied Chinese Support Package which can be downloaded at this address:.I suggest the friend like me to learn and exercise this method.

  So I have a mind,it's developing a part of our project in english.For example:private message management model in our project or other model.We can analyse,design,and code this model in english.

  Another,we can communicate each other in my website in english.In this way,we can learn english by using it.Of course,we should also take some other method introduced in manual writed by generals Zhong DaoLong.

  In order to learn english,I will write some type of diary in english,for example:nurture my daughter,felling in my life,and learn jsp.

  I hope there are many friend can join the team of learning english.

学习raorao的PostAdvice0Action.java

我在beforePostArt指的提交文章前的target,当提交文章后,这个target会保存在session

中。当重复提交失败后,页面会定向到beforePostArt所指的target。

因为raorao如果不改定向,提交日记定向的是diarysuccess所指的toSendMailOfGoalAction.do,这个target

提交日记前就已经保留在了session的beforePostArt中。重复提交日记失败后,调用

beforePostArt所指的target,自然就定向到了diarysuccess所指的toSendMailOfGoalAction.do,

就形成了重复发送邮件。

所以,raorao把重复提交日记失败后的target用isBackSubmit重新定向,避免了一般情况下的重复发送邮件。

但由于learndiaryV0.9本身没有彻底解决重复提交问题,在此基础上形成防止重复发送日记的代码在重复提交日记

成功后自然就被绕过了。而这正是学习日记程序设计队现在正在解决的目标之一。

 

学习日记大事记

这篇日记用于记载学习日记网站发生的具有里程碑意义的事件。

1、2004年9月28日,中秋节,学习日记投入运行;

2、2004年11月18日,学习日记开发小组正式成立;

3、约2005年6月,将学习日记的代码提交到http://www.tigris.org开源社区,成立学习日记开源项目http://learndiary.tigris.org

 4、2007年6月中旬,停用Java版学习日记,关闭学习日记开源项目,学习日记改为使用wordpress搭建的个人博客。

老鼠成了替罪羊

    前几天,我看见咪妹手中的一件刚才还在玩的玩具丢了,我问她玩具到哪里去了。她一脸严肃,非常慎重的说了两个字:“耗耗。”。那样的神态就像福尔摩斯断案后的肯定。

    于是,我发现,只要我们问她某样东西哪里去了的时候,她都会这样一本正经的回答“耗耗。”。我估计是我不在家的时候,大人把她喜欢的东西藏起来的时候这样告诉她的。于是,老鼠成了替罪羊。

    问题是,我们大人应不应该以这样的方式骗她呢?

在倡议进行信息时代学习理论讨论的同时进行

    在需求分析设计队队长J_Key的来信的启发下,我删除了公告中的大部分其他公告,添加了开发小组成员参与新版学习平台的战略规划的帖子。希望大家可以在此或在学习日记创意集锦这个目标中展开新版学习平台未来的思考、讨论与建议。我觉得大家可以在学习日记创意集锦这个目标的日记中记录一些思考的过程,在战略规划的这个公告的评论中提出思考的结论。我会陆续在前者的日记中作一些学习理论和创意的思考。

    上周联系了一名学习理论的顾问,还在等待回复中。如果有了学习理论顾问的理论支援,我想我们的新版学习平台的理论指导会更完备的。

    上周开始在学习<<系统分析与设计>> 这本书的同时,学习javauml这本软件工程的电子书,为协助需求分析设计队队长J_Key的工作作准备。

    今天是圣诞节,我们这里地处内地,除了一些年龄不大的年青人参与赶时髦外,基本上没有过节的气氛。大家还是向往常一样过周末。不过,我想在学习日记开发小组的成员中,肯定有不少朋友正在欢度圣诞节。在这里祝他们圣诞节快乐。

    现在,临近过年了,大家都很忙,尤其是学生还要考试,我估计开发小组的工作会暂时比较宁静。但学生考试结束后,我想会热闹起来。只不过不知道他们什么时候放寒假。

开始学习javauml电子书

在看<<系统分析与设计>>这本书的同时,我开始看javauml这本英语版的电子书,上周看了10多页,由于英语水平有限,懂了个大概意思。这本书的起点较低,就是不懂uml和oop的人也可使用,只要有点java基础。作者先前写vbuml。

    这本书的重点是uml,用于jsp+tomcat的非商业应用,没有讲struts。(ucommercially available through Rational Software called the Unified Process and one from my own experiences called Synergy. The greatest emphasis will be placed on the Unified Process.)

    先讲了不应用uml的困境,然后讲了迭代和增量的区别。懂了个大概。

    我看这本书的目的是配合<<系统分析与设计>>的学习,用于把uml用于jsp程序的建模的实践。

抛砖引玉--关于新版学习平台的一点设想

我认为,新版学习平台可以采用下面的开发流程:

    总体战略规划-

                       一期计划-一期分析-一期设计-一期实施-一期推广并完善-

                                                                                                                二期计划-二期分析-二期设计-二期实施-二期推广并完善-

                                                                                                                                                                                                     三期计划-三期分析-三期设计-三期实施-三期推广并完善。。。

    这是一种螺旋模型,逐渐完成我们的目标,先完成必须的、风险小的,随着我们经验的增加,再完成风险大的。

一期计划:完成大家写日记的日记系统,可以把learndiaryV0.9.0.3看作探索型原型。推广我们的系统;

二期计划:加入专家智能系统(广义的),从目标确定,过程指导,经验总结,在系统中用一整套机制(资料库,真实专家参与,目标完成分析系统)。推广我们的系统;

三期计划:加入其他一些为学习服务的特性,所有使用我们这个平台的网站以程序的机制形成联盟,提供以人为本的,为一个一生中的所有学习项目提供一揽子解决方案的大网校。推广我们的系统。

    以上是我关于规划的一点初步想法,肯定很不成熟甚至错误,仅在此起一个抛砖引玉的作用,希望大家把你们的玉石一块一块的朝我砸过来吧。

    还有,酒好还怕巷子深。我觉得学习日记开发小组有必要组成一个宣传队,宣传我们的产品,争取我们的外授。

    祝大家圣诞节快乐!

jjj提出的文档规范(转自jjj)

对于文档的设计,我觉得必须有一个普遍的规范,并且这个规范必须可以对项目的开发起到好的效果!

所以我认为(个人观点,仅限于开发部分的文档,至于需求部分大家可以共同讨论)

1.数据库的设计(或者说PO持久化层的设计),必须有一个明确的文档,这个文档中描述了各个表之间的关系

。每个属性对其他表中的数据是怎样影响的,对应关系是什么样的。比如说:一个属性对应另外一个表,并且

是一对多关系,我们就可以明显的看出通过这个属性获得的是一个List;如果是一对一关系,就可以知道,他们

共用一个ID,通过这个实体就可以获得另外一个实体(DAO.load("***Id));如果是多对一关系,我们就要考虑

在编写EJB的时候是否需要通过懒加载(Lazy

)的方法获得这个po。

2.Action和ActonForm的文档

 

必须重视他们,虽然他们有时看来很简单,如果可以有一个详尽的文档,对开发action来说很有帮助。

  我举个我们写的文档 的例子吧:

  2.1概述

     在**详细信息页面(**Detail.jsp)上的保存按钮所调用的Action。

    2.2数据session传输方式

   从session获取数据列表:

   获取名称   参数类型    参数说明

    **Form    **Form **Form

    2.3 属性

无。

     4.4 数据request传输方式

     从request获取数据列表:

     获取名称 参数类型 参数说明

      在request存入数据列表:

      存入名称   参数类型 参数说明

     4.5调用ejb的接口描述

      接口名称:ejb.**.**. **

      方法名称:public void save**(PO  po,List  **,List        **)throws

DataOperationException,RemoteException

        方法说明:保存**单和**电路;

      返回值:void

     4.6 异常处理

      异常:DataOperationException

      错误号:处理异常时与输出信息相对应的错误编号

      说明:数据操作异常

      跳转路径:error(所有的出错信息都跳转到这个页面)

     4.7 功能描述

     

**详细信息页面(**Detail.jsp)上的保存按钮所调用的Action,将修改后的受理单保存。

     4.8 逻辑实现

      1.获取**Form;

     

2.从**Form中提取出**单po信息,和需要删除的电路列表deleteList和要保存的列表saveList;

      3.调用ejb方法public void save**(PO  po,List  save**List,List 

**List)throws

DataOperationException,RemoteException,来保存受理单、接入电路;

       4.如果保存成功则删除**Form;

      5.如果成功,则forward=success, page=**Success.jsp;

      6.否则,转向错误页面**Error.jsp

希望大家写代码一定要参照代码规范(转自kula)

1. Java 命名约定

除了以下几个特例之外,命名时应始终采用完整的英文描述符。此外,一般应采用小写字母,但类名、接口名以及任何非初始单词的第一个字母要大写。

1.1 一般概念

n 尽量使用完整的英文描述符

n 采用适用于相关领域的术语

n 采用大小写混合使名字可读

n 尽量少用缩写,但如果用了,要明智地使用,且在整个工程中统一

n 避免使用长的名字(小于 15 个字母是个好主意)

n 避免使用类似的名字,或者仅仅是大小写不同的名字

n 避免使用下划线(除静态常量等)

1.2 示范

包(Package) 采用完整的英文描述符,应该都是由小写字母组成。对于全局包,将你的 Internet 域名反转并接上包名。 java.awt,com.learndiary.www.persistence

类(Class) 采用完整的英文描述符,所有单词的第一个字母大写。 Customer, SavingsAccount

接口(Interface) 采用完整的英文描述符说明接口封装,所有单词的第一个字母大写。习惯上,名字后面加上后缀 able, ible 或者 er,但这不是必需的。 Contactable,Prompter

组件/部件(Component) 使用完整的英文描述来说明组件的用途,末端应接上组件类型。 okButton, customerList,fileMenu

异常(Exception) 通常采用字母 e 表示异常。 e

类变量 字段采用完整的英文描述,第一个字母小写,任何中间单词的首字母大写。 firstName, lastName

实参/参数 同字段/属性的命名规则 public void setFirstName(String firstName){ this.firstName = firstName;}

局部变量 同字段/属性的命名规则

获取成员函数 被访问字段名的前面加上前缀 get。 getFirstName(), getLastName()

布尔型的获取成员函数 所有的布尔型获取函数必须用单词 is 做前缀。 isPersistent(), isString()

设置成员函数 被访问字段名的前面加上前缀 set。 setFirstName(), setLastName(),setWarpSpeed()

普通成员函数 采用完整的英文描述说明成员函数功能,第一个单词尽可能采用一个生动的动词,第一个字母小写。 openFile(), addAccount()

静态常量字段(static final) 全部采用大写字母,单词之间用下划线分隔。 MIN_BALANCE, DEFAULT_DATE

循环计数器 通常采用字母 i,j,k 或者 counter 都可以接受。 i, j, k, counter

数组 数组应该总是用下面的方式来命名:objectType[]。 byte[] buffer;

2. Java 注释约定

一个很好的可遵循的有关注释的经验法则是:问问你自己,你如果从未见过这段代码,要在合理的时间内有效地明白这段代码,你需要哪些信息。

2.1. 一般概念

n 注释应该增加代码的清晰度

n 保持注释的简洁

n 在写代码之前写注释

n 注释出为什么做了一些事,而不仅仅是做了什么

2.2. 示范

文档注释 在紧靠接口、类、成员函数和字段声明的前面注释它们。 /** 客户:客户是我们将服务和产品卖给的人或机构。*/

C 语言风格 采用 C 语言风格的注释去掉不再使用但你仍想保留的代码。仍想保留是因为用户万一会改变想法,或者在调试过程中想让它暂时失效。 /* 这部分代码因为已被它之前的代码取代,由 B.Gustafsson, 于 1999 年 6 月 4 日注释掉。如果两年之后还未使用,将其删除。. . . (源代码)*/

单行 在成员函数内采用单行注释,来说明业务逻辑、代码段和暂时变量的声明。注释符"//"后必须紧跟一个空格,然后才是注释信息。 // 遵照 Sarek 的规定,给所有// 超过 $1000 的发货单// 打 5% 的折扣。让利活// 动于 1995年 2 月开始.

2.3. 注释哪些部分

类 类的目的、即类所完成的功能,注释出采用的不变量。

接口 设置接口的目的、它应如何被使用以及如何不被使用。

成员函数注释 对于设置与获取成员函数,在成员变量已有说明的情况下,可以不加注释;普通成员函数要求说明完成什么功能,参数含义是什么返回什么;

普通成员函数内部注释 控制结构,代码做了些什么以及为什么这样做,处理顺序等。

实参/参数 参数含义、及其它任何约束或前提条件

字段/属性 字段描述

局部变量 无特别意义的情况下不加注释

3. Java 文件样式约定

所有的 Java(*.java) 文件都必须遵守如下的样式规则:

1) 版权信息

版权信息必须在 java 文件的开头,比如:

/** * Copyright ? 2000 Shanghai XXX Co. Ltd. * All right reserved. */

其他不需要出现在 javadoc 的信息也可以包含在这里。

2) Package/Imports

package 行要在 import 行之前,import 中标准的包名要在本地的包名之前,而且按照字母顺序排列。如果 import 行中包含了同一个包中的不同子目录,则应该用 * 来处理。

package hotlava.net.stats;import java.io.*;import java.util.Observable;import hotlava.util.Application;

这里 java.io.* 是用来代替InputStream and OutputStream 的。

3) Class

接下来的是类的注释,一般是用来解释类的。

/** * A class representing a set of packet and byte counters * It is observable to allow it to be watched, but only * reports changes when the current set is complete */

接下来是类定义,包含了在不同的行的 extends 和 implements

public class CounterSet extends Observable implements Cloneable{……}

4) Class Fields

接下来是类的成员变量:

/** * Packet counters */protected int[] packets;

public 的成员变量必须生成文档(JavaDoc)。proceted、private和 package 定义的成员变量如果名字含义明确的话,可以没有注释。

5) 存取方法(类的设置与获取成员函数)

接下来是类变量的存取的方法。它只是简单的用来将类的变量赋值获取值的话,可以简单的写在一行上,如类的成员变量已经有注释,类变量的存取方法可以没有注释。

public int[] getPackets() { return this.packets; }public void setPackets(int[] packets) { this.packets = packets; }……

要求说明的是,对于集合,加入成员函数来插入和删除项;另其它的方法不要写在一行上。

6) 构造函数

接下来是构造函数,它应该用递增的方式写(比如:参数多的写在后面)。

public CounterSet(int size){ this.size = size;}

7) 克隆方法

如果这个类是可以被克隆的,那么下一步就是 clone 方法:

public Object clone() { try { …… }catch(CloneNotSupportedException e) { …… }}

8) 类方法 (类的普通成员函数)

下面开始写类的方法:

/** * Set the packet counters * param r1 - …… * param r2 - …… * …… */protected final void setArray(int[] r1, int[] r2, int[] r3, int[] r4) throws IllegalArgumentException{ // Ensure the arrays are of equal size ……}

9) toString 方法

一般情况下,每一个类都应该定义 toString 方法:

public String toString() { ……}

10) main 方法

普通类,考虑置入一个main()方法,其中包含用于测试那个类的代码,如果包含了main() 方法, 那么它应该写在类的底部。

4. Java编码其它约定

n 文档化

必须用 javadoc 来为类生成文档。不仅因为它是标准,这也是被各种 java 编译器都认可的方法。使用 @author 标记是不被推荐的,因为代码不应该是被个人拥有的。

n 缩进

缩进应该是每行2个空格。 不要在源文件中保存Tab字符, 在使用不同的源代码管理工具时Tab字符将因为用户设置的不同而扩展为不同的宽度。

如果你使用 UltrEdit 作为你的 Java 源代码编辑器的话,你可以通过如下操作来禁止保存Tab字符, 方法是通过 UltrEdit中先设定 Tab 使用的长度室2个空格,然后用 Format|Tabs to Spaces 菜单将 Tab 转换为空格。

n 页宽

页宽应该设置为80字符。 源代码一般不会超过这个宽度, 并导致无法完整显示, 但这一设置也可以灵活调整。 在任何情况下, 超长的语句应该在一个逗号或者一个操作符后折行。 一条语句折行后, 应该比原来的语句再缩进2个字符。

n {} 对

{} 中的语句应该单独作为一行。 例如, 下面的第1行是错误的, 第2行是正确的:

if (i>0) { i ++ }; // 错误, { 和 } 在同一行 if (i>0) { i ++ }; // 正确, 单独作为一行

n 括号

左括号和后一个字符之间不应该出现空格; 同样, 右括号和前一个字符之间也不应该出现空格。 下面的例子说明括号和空格的错误及正确使用:

CallProc( AParameter ); // 错误

CallProc(AParameter); // 正确

不要在语句中使用无意义的括号,括号只应该为达到某种目的而出现在源代码中。

n JSP文件命名

采用完整的英文描述说明JSP所完成的功能,尽可能包括一个生动的动词,第一个字母小写,如:viewMessage.jsp、editUser.jsp或者forumChooser.jsp等。

n Servlet类命名

一般对应于所服务的对象加后缀Service来命名,如:UserService,TradeService等。

5. 一些编程建议

n 使用 StringBuffer 对象

在处理 String 的时候要尽量使用 StringBuffer 类,StringBuffer 类是构成 String 类的基础。String 类将 StringBuffer 类封装了起来,(以花费更多时间为代价)为开发人员提供了一个安全的接口。当我们在构造字符串的时候,我们应该用 StringBuffer 来实现大部分的工作,当工作完成后将 StringBuffer 对象再转换为需要的 String 对象。比如:如果有一个字符串必须不断地在其后添加许多字符来完成构造,那么我们应该使用 StringBuffer 对象和它的 append() 方法。如果我们用 String 对象代替 StringBuffer 对象的话,会花费许多不必要的创建和释放对象的 CPU 时间。

n 避免太多的使用 synchronized 关键字

避免不必要的使用关键字 synchronized,应该在必要的时候再使用它,这是一个避免死锁的好方法。 必须使用时,也尽量控制范围,最好在块级控制。

n 避免使用 java.util.Vector 类

因为"Unlike the new collection implementations, Vector is synchronized.",所以使用java.util.Vector类在性能上会有所减低。

n 尽量使用接口而不是一个具体的类

比方如下需求,给定一个SQL语句,返回一个对象的列表,实现中用java.util.ArrayList实现,于是定义方法为:

public java.util.ArrayList getObjectItems(String sql)

上面的方法存在一个问题,当getObjectItems内改用Vector或LinkedList实现,外部类必须做相应更改。一个更好的方法是定义返回值为java.util.AbstractList更合适:

public java.util.AbstractList getObjectItems(String sql)

这样即使更改实现,外部类也不必做相应更改。

n 避免使用索引来调用数据库中间层组件返回的结果集

如:

for(int i=1; i<=dt.getRowCount(); i++){ String field1 = dt.getField(i, 0).toString(); ……}

而应用字段名来存取结果集:

for(int i=1; i<=dt.getRowCount(); i++){ String field1 = dt.getField(i, "field1").toString(); ……}

这样在数据库设计更改或查询的SQL语句发生变化时,不会影响到程序的执行。

n 一行不能超过80个字

n 函数能写一行的话就写一行.比如 public bealean isLearn(){ return false; }

n 除非上面的情况.括号单独占一行.

//code example

package querysms;

import java.util.*;

import java.text.*;

public class test

{

    public static void main(String[] argv)

    {

        GregorianCalendar d1=new GregorianCalendar(1986,04,05);

        GregorianCalendar d2=new GregorianCalendar();

        Calendar d3=Calendar.getInstance();

        System.out.println("It was then"+d1.getTime());

        System.out.println("It is now"+d2.getTime());

        System.out.println("It is now"+d3.getTime());

        d3.set(Calendar.YEAR,1915);

        d3.set(Calendar.MONTH,Calendar.APRIL);

        System.out.println("D3 set to "+d3.getTime());

    }

}