JavaEE编程规范中级.docx
《JavaEE编程规范中级.docx》由会员分享,可在线阅读,更多相关《JavaEE编程规范中级.docx(18页珍藏版)》请在冰豆网上搜索。
JavaEE编程规范中级
开发编程规范
J2ee项目一般是大型项目,大型项目都需要团队协作开发。
团队协作开发的成功需要一致的开发规范。
对软件进行后续的维护成本远远要大于它最初的开发成本,保证开发的系统是可持续工作易于维护就至关重要了。
可靠的OO设计原理实践及一个良好的JAVA编程规范在整个J2EE项目生命周期中变得十分重要。
在团队开发中,应该保持所有的代码上都乎合-1-一个相同的标准,并且代码在风格上应该保持一致。
JAVA编程标准为什么会显得这么重要呢?
我们经常会发生这样的情况:
太注重于j2ee的某方面的技术细节,而乎略了良好的程序设计和编程习惯。
太多的J2EE项目的失败就是因为在项目中含有太多草率的代码,使得整个系统变得脆弱、不可维护,最终只得放弃整个项目。
关于编程规范,它是一个巨大的领域。
在这里不作详细的阐述。
这里只列出了在实际J2EE开发中十分重要的问题进行讨论,同时对这些问题有不同的见解和解决方法。
一切都应该以实践为主。
一、不要去发明自己的标准
几乎每一门编程语言都有自己的一套编程标准,但是千万不要去发明自己的编程标准。
Java是一门简单的语言,我们应该以sun的java编程标准作为准则。
在它的基础上进行扩充。
比如C++语言使用的匈牙利命名法,并不适合用于在JAVA。
也千万不要在一种开发语言中使用另外一种开发语言的编程标准。
二、java类中代码的组织结构
1.按照方法的功能,而不是按照方法的可访问性来组织方法。
比如:
不是把所有的public方法放在private方法的前面,而是把一个private方法放成使用它的那些public方法的附近。
2.类的组织约定
静态变量和方法。
成员变量。
构造函数。
接口的实现方法,连同支持它们的私用方法
该类独有的公有方法(不包括已实现接口的公用方法)。
抽像保护方法
提供给子类使用的保护方法
与前面任何一组都无关的实现方法。
三、按职责进行分类,做你该做的事情!
每一个类应该具有一个明确的职责,不要把它相干和不相干的代码都填进来。
那些不相干的代码应该重构为另一个单独的类或者是助手类。
如果一个不同概念级别上的代码对相同的对象重复调用,那么它可能需提升为一个父类。
而其它对象通过继承这个父类。
通过把相干的重复代码提取到父类和把不相干的代码重构为一个助手类是解决代码重复的常用方法。
这样可以阻止一个类的爆炸式增长,变成一个臃肿的类。
一个类,包括Javadoc和内部注释,如果超过了500行代码,它都是需要重构的候选者。
因为它可能已经承担了太多的职责。
可以运用策略模式来用一个接口把原类与助手类分开,实现助手类在不同的情况可以有不同的实现。
来提高系统的灵活性。
每一个方法都应该具有一个单一而清晰明确的职责。
否则这个方法应该进行重构。
同时这也可以防止方法变得很长。
publicStringaddCounter(CounterDTOcounter)throwsBusinessException{
Stringbuffer="00000000";
//读取seqence
StringsequenceStr=(String)this.getSqlMapClientTemplate()
.queryForObject(SqlID.GET_COUNTER_PK,null);
intseqLength;
seqLength=sequenceStr.length();
StringcounterNo="";
StringregionCode=counter.getRegionCode();
if(regionCode.length()>2){
regionCode=regionCode.substring(0,2);
}
counterNo=regionCode
+buffer.substring(0,buffer.length()-seqLength)
+sequenceStr;
counter.setCounterNo(counterNo);//设置主键
sqlMap.insert(SqlID.ADD_COUNTER,counter);//插入柜面数据
returnpk;
}
上面的方法是新增一个柜面信息,它有三个步聚:
1.读取指定的sequence,获得一个唯一柜面流水号
2.根据柜面的机构代码和流水号产生一个唯一8位的柜面号,柜面号由两位的机构代码+6位的流水号组成。
流水号不足6位,在前面以0补充。
3.设置柜面信息的柜面号为新产生的柜面号,并插入数据库,成功则返回新的柜面号。
重构后的代码:
//读取sequence,获得流水号
privateStringgetCounterSequenceNo()throwsBusinessException{
return(String)this.getSqlMapClientTemplate().queryForObject(
SqlID.GET_COUNTER_PK,null);
}
//根据机构代码来生成柜面号
privateStringgenerateCounterNo(StringregionCode)
throwsBusinessException{
Stringbuffer="00000000";
StringsequenceStr=this.getCounterSequenceNo();
intseqLength;
seqLength=sequenceStr.length();
StringcounterNo="";
if(regionCode.length()>2){
regionCode=regionCode.substring(0,2);
}
counterNo=regionCode
+buffer.substring(0,buffer.length()-seqLength)
+sequenceStr;
returncounterNo;
}
//新增柜面
publicStringaddCounter(CounterDTOcounter)throwsBusinessException{
Stringpk=null;
pk=this.generateCounterNo(counter.getRegionCode());//产生主键
counter.setCounterNo(pk);//设置主键
sqlMap.insert(SqlID.ADD_COUNTER,counter);//插入柜面数据
returnpk;
}
重构后的代码大大的便于阅读和维护。
使方法具有明确的责任。
注意在重构的时候,通过我们把那些相对独立的任务变成一个私有的方法。
关于一个方法应该限制为多长,没有明确的规定。
它应该以人的舒服度为主。
一个方法包括注释(不含javadoc)的实现代码能够在一屏中可以进行阅读。
否则它就应该需要进行重构。
一般来说,一个方法的代码控制在30-40行是最佳的。
四、避免重复的代码
在一个类中,可能在各个方法中产生了相同的代码块。
这就是重复的代码。
重复的代码是难以维护和难以理解的。
有一个类其中有两个方法如下:
//发送一个包裹
publicStringdeliveryWarePack(WarePackDTOwarePack)
throwsBusinessException{
CommonDAOFactoryfactory=(CommonDAOFactory)this.context
.getBean(CommonDAOFactory.COMMON_DAO_FACTORY_BEAN_NAME);
WarePackDAOwarePackDAO=(WarePackDAO)factory.getDAOByRegionCode(
this.WARE_PACK_DAO_NAME,"00");
//…………
}
//根据包号得到包信息
publicWarePackDTOgetWarePackByPackNum(StringpackNum)
throwsBusinessException{
CommonDAOFactoryfactory=(CommonDAOFactory)this.context
.getBean(CommonDAOFactory.COMMON_DAO_FACTORY_BEAN_NAME);
WarePackDAOwarePackDAO=(WarePackDAO)factory.getDAOByRegionCode(
this.WARE_PACK_DAO_NAME,"00");
//………
}
这似乎没有任何问题,但是这样的代码重复可能会导致严重的问题。
1.太多的代码:
如果重构后只用两行就可以了
2.令阅读者迷惑不解,阅读者可能会对开发人员产生怀疑,认为这两处是两个不相同的代码,从而去进行比较,花费更多的时间和精力。
3.造成修改的不一致,经常可能发现对一个方法进行了修改,而忘记也应该对另一个方法也进行相同的修改。
增加代码的维护量。
修改后的代码:
privateWarePackDAOwarePackDAO=getWarePackDAO();
privateCommonDAOFactorygetFactory(){
CommonDAOFactoryfactory=(CommonDAOFactory)this.context
.getBean(CommonDAOFactory.COMMON_DAO_FACTORY_BEAN_NAME);
returnfactory;
}
privateWarePackDAOgetWarePackDAO(){
WarePackDAOdao=(WarePackDAO)this.getFactory().getDAOByRegionCode(
this.WARE_DAO_NAME,"00");
returndao;
}
//发送一个包裹
publicStringdeliveryWarePack(WarePackDTOwarePack)
throwsBusinessException{
StringpackNumber=this.warePackDAO.insertWarePack(warePack);
}
//根据包号得到包信息
publicWarePackDTOgetWarePackByPackNum(StringpackNum)
throwsBusinessException{
WarePackDTOwarePack