您的位置:首页>软件开发>开发经验与感悟>

敏捷开发的必要技巧:将注释转为代码

[ 来源:Wingel’s javablog | 更新日期:2007-7-15 20:19:58 | 评论 0 条 | 我要投稿 ]
示例

这是一个会议管理系统. 在会议中,每个参会者都会戴一个牌子,这牌子上面有这个参会者的信息(比如姓名之类的).在这个系统中,Badge这个类用来存放这个参会者的信息.请看一下下面的代码跟注释:



//存放参会者身上戴的牌子所显示的信息. public class Badge { String pid; //参会者 ID String engName; //英文全名 String chiName; //中文全名 String engOrgName; //所在部门英文名称 String chiOrgName; //所在部门中文名称 String engCountry; //部门所在国家的中文名称 String chiCountry; //部门所在国家的英文名称 //*********************** //构造函数. //根据参会者的id,去数据库取出该参与者的信息. //*********************** Badge(String pid) { this.pid = pid; //*********************** //取出参会者 //*********************** ParticipantsInDB partsInDB = ParticipantsInDB.getInstance(); Participant part = partsInDB.locateParticipant(pid); if (part != null) { //取出参会者的英文全名 engName = part.getELastName() + ", " + part.getEFirstName(); //取出参会者的中文全名 chiName = part.getCLastName()+part.getCFirstName(); //*********************** //取出所在部门跟国家. //*********************** OrganizationsInDB orgsInDB = OrganizationsInDB.getInstance(); //取出所在部门的id. String oid = orgsInDB.getOrganization(pid); if (oid != null) { Organization org = orgsInDB.locateOrganization(oid); engOrgName = org.getEName(); chiOrgName = org.getCName(); engCountry = org.getEAddress().getCountry(); chiCountry = org.getCAddress().getCountry(); } } } ... } 字串1


将注释转换为代码,让代码足够清楚到可以表示注释

我们先看一下第一个注释:


//存放参会者身上戴的牌子所显示的信息. public class Badge { ... }


我们干嘛需要这个注释呢?因为程序员认为"Badge"这个类名不足以让读代码的人清楚这个类的作用,所以就写了这个注释. 那如果我们直接将注释所表达的一些信息放在类名里面的话,就没有单独写注释的必要了.比如::


public class ParticipantInfoOnBadge { ... }


其实很多人肯定会问?难道写注释不是一个好的编程习惯吗?这问题很好,我也想知道.在解释之前,我们先把这个示例中所有的注释都转为代码先.

将注释转换为变量名


Consider: public class ParticipantInfoOnBadge { String pid; //参会者 ID String engName; //英文全名 String chiName; //中文全名 String engOrgName; //所在部门英文名称 String chiOrgName; //所在部门中文名称 String engCountry; //部门所在国家的中文名称 String chiCountry; //部门所在国家的英文名称 ... }
字串6



这里,我们就像对属性的注释,转化为属性名, 比如:


public class ParticipantInfoOnBadge { String participantId; String participantEngFullName; String participantChiFullName; String engOrgName; String chiOrgName; String engOrgCountry; String chiOrgCountry; ... }


对参数的注释,转化为参数名

看看:


public class ParticipantInfoOnBadge { ... //*********************** //构造函数. //根据参会者的id,从数据库取出该参与者的信息. //*********************** ParticipantInfoOnBadge(String pid) { this.pid = pid; ... } }


比如:

字串9
public class ParticipantInfoOnBadge { ... //*********************** //构造函数. //从数据库取出该参与者的信息. //*********************** ParticipantInfoOnBadge(String participantId) { this.participantId = participantId; ... } }


将注释转换为方法的一部分

上面的构造函数中,有两句注释,第一句我们已经解决了,那么还有"从数据库取出该参与者的信息"? 这句注释描述了,这个构造函数是如何实现的(就是从数据库里面取出信息),我们将这句话转化:


public class ParticipantInfoOnBadge { ... //*********************** //构造函数. //*********************** ParticipantInfoOnBadge(String participantId) { loadInfoFromDB(participantId);//现在,看一下这个构造函数内部,我们就能知道这个构造函数是做什么了吧. } void loadInfoFromDB(String participantId) { this.participantId = participantId; ... } } 字串9


删掉没用的注释

有时候,我们会碰到一些注释,很明显没什么用处的,比如:


public class ParticipantInfoOnBadge { ... //*********************** //构造函数. //*********************** ParticipantInfoOnBadge(String participantId) { ... } }


就算去掉这些注释,我们也能看得出来,这是个构造函数.这个注释并没什么用处.
什么样的类是看代码的人最喜欢的?那就是简单易看的类.一个设计得好的类,能够让人家一眼就能出你这个类都有些什么东西,明白你这个类都做了一些什么事.如果看这个类的时候,要不停的将屏幕滚来滚去,而思维还要随屏幕的滚动跳转,无形中,看懂这个类需要花的时间就多了.
一个屏幕,差不多只能显示20行左右的代码,而这个没用的注释,一下子就占用了3行的代码,一些有用的信息反而被挤掉了(比如说代码),得不偿失啊!我看还是赶紧移除这个注释:
字串7
public class ParticipantInfoOnBadge { ... ParticipantInfoOnBadge(String participantId) { ... } }


将一部分代码重构成方法,用方法名来表达注释的意思

先看看下面这个注释:


void loadInfoFromDB(String participantId) { this.participantId = participantId; //*********************** //取得参会者的全名. //*********************** ParticipantsInDB partsInDB = ParticipantsInDB.getInstance(); Participant part = partsInDB.locateParticipant(participantId); if (part != null) { //取得参会者的英文全名. engFullName = part.getELastName() + ", " + part.getEFirstName(); //取得参会者的中文全名. chiFullName = part.getCLastName()+part.getCFirstName(); //*********************** //取得参会者所在部门和国家. //*********************** OrganizationsInDB orgsInDB = OrganizationsInDB.getInstance(); //取得参会者被雇佣部门的id. String oid = orgsInDB.getOrganization(participantId); if (oid != null) { Organization org = orgsInDB.locateOrganization(oid); engOrgName = org.getEName(); chiOrgName = org.getCName(); engOrgCountry = org.getEAddress().getCountry(); chiOrgCountry = org.getCAddress().getCountry(); } } }

字串2




现在我们已经看清这段注释要表达一些什么信息,如果要使代码跟注释一样清楚,我们可以将注释所解释的那部分代码抽取出来,做成一个方法,然后让方法名来表达注释的意思.如果可以的话,我们就不需要额外的注释了:


void loadInfoFromDB(String participantId) { this.participantId = participantId; getParticipantFullNames(); //(取得参会者的全名,注意,我们已经将注释去掉了.) //*********************** //取得参会者所在部门和国家. //*********************** //取得参会者被雇佣部门的id. OrganizationsInDB orgsInDB = OrganizationsInDB.getInstance(); String oid = orgsInDB.getOrganization(participantId); if (oid != null) { Organization org = orgsInDB.locateOrganization(oid); engOrgName = org.getEName(); chiOrgName = org.getCName(); engOrgCountry = org.getEAddress().getCountry(); chiOrgCountry = org.getCAddress().getCountry(); } } void getParticipantFullNames() { ParticipantsInDB partsInDB = ParticipantsInDB.getInstance(); Participant part = partsInDB.locateParticipant(participantId); if (part != null) { //取得参会者的英文全名. engFullName = part.getELastName() + ", " + part.getEFirstName(); //取得参会者的中文全名. chiFullName = part.getCLastName()+part.getCFirstName(); } } 字串1


此外,还有一个注释:"取得参会者所在部门和国家",也是可以重构在方法名里面的:


void loadInfoFromDB(String participantId) { this.participantId = participantId; getParticipantFullNames(); getOrgNameAndCountry(); //又抽取掉了一个注释 } void getParticipantFullNames() { ParticipantsInDB partsInDB = ParticipantsInDB.getInstance(); Participant part = partsInDB.locateParticipant(participantId); if (part != null) { //取得参会者的英文全名. engFullName = part.getELastName() + ", " + part.getEFirstName(); //取得参会者的中文全名. chiFullName = part.getCLastName()+part.getCFirstName(); } } void getOrgNameAndCountry() { OrganizationsInDB orgsInDB = OrganizationsInDB.getInstance(); //取得参会者被雇佣部门的id. String oid = orgsInDB.getOrganization(participantId); if (oid != null) { Organization org = orgsInDB.locateOrganization(oid); engOrgName = org.getEName(); chiOrgName = org.getCName(); engOrgCountry = org.getEAddress().getCountry(); chiOrgCountry = org.getCAddress().getCountry(); } }

字串2




抽取出方法,放于另一个类

请看一下下面这两个注释:


public class ParticipantInfoOnBadge { ... void getParticipantFullNames() { ParticipantsInDB partsInDB = ParticipantsInDB.getInstance(); Participant part = partsInDB.locateParticipant(participantId); if (part != null) { //取得参会者的英文全名. engFullName = part.getELastName() + ", " + part.getEFirstName(); //取得参会者的中文全名. chiFullName = part.getCLastName()+part.getCFirstName(); } } }


因为程序员觉得,这些代码片段还是不够清楚,所以还是要用注释还解释它们. 但这回移除注释时,我们会将抽取出来的方法,放到Participant这个类里面,而不是ParticipantInfoOnBadge了:


public class ParticipantInfoOnBadge { ... void getParticipantFullNames() { ParticipantsInDB partsInDB = ParticipantsInDB.getInstance(); Participant part = partsInDB.locateParticipant(participantId); if (part != null) { engFullName = part.getEFullName(); //将职责交给domain自己,也就是Participant. chiFullName = part.getCFullName(); } } } public class Participant { String getEFullName() { return getELastName() + ", " + getEFirstName(); } String getCFullName() { return getCLastName() + getCFirstName(); } }
字串7



用注释去命名一个已经存在的方法

请看下面的注释,也是这个例子中的最后一个注释了:


public class ParticipantInfoOnBadge { ... void getOrgNameAndCountry() { OrganizationsInDB orgsInDB = OrganizationsInDB.getInstance(); //取得参会者被雇佣部门的id. String oid = orgsInDB.getOrganization(participantId); if (oid != null) { Organization org = orgsInDB.locateOrganization(oid); engOrgName = org.getEName(); chiOrgName = org.getCName(); engOrgCountry = org.getEAddress().getCountry(); chiOrgCountry = org.getCAddress().getCountry(); } } }


我们之所以要用这个注释"取得参会者被雇佣部门的id",是因为这个方法名"getOrganization"取得不够清楚. 所以,我们将注释表达的信息,放在这个方法名里面:

字串3




public class ParticipantInfoOnBadge { ... void getOrgNameAndCountry() { OrganizationsInDB orgsInDB = OrganizationsInDB.getInstance(); String oid = orgsInDB.findOrganizationEmploying(participantId); if (oid != null) { Organization org = orgsInDB.locateOrganization(oid); engOrgName = org.getEName(); chiOrgName = org.getCName(); engOrgCountry = org.getEAddress().getCountry(); chiOrgCountry = org.getCAddress().getCountry(); } } } public class OrganizationsInDB { ... void findOrganizationEmploying(String participantId) { ... } }


pdf下载:http://www.blogjava.net/Files/Wingel/敏捷开发的必要技巧第1,2章.rar




Tags:
责任编辑:
您的评论
用户名: 新注册) 密码: 匿名评论 [所有评论]

·用户发表意见仅代表其个人意见,并且承担一切因发表内容引起的纠纷和责任
·本站管理人员有权在不通知用户的情况下删除不符合规定的评论信息或留做证据
·请客观的评价您所看到的资讯,提倡就事论事,杜绝漫骂和人身攻击等不文明行为