专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »项目管理 » 敏捷开发:敏捷开发中如何将注释转换为代码 »正文

敏捷开发:敏捷开发中如何将注释转换为代码

来源: 发布时间:星期五, 2009年1月9日 浏览:34次 评论:0
  举例

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

//存放参会者所戴牌子显示信息
public 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);
(part != null) {
//取出参会者英文全名
engName = part.getELastName + ", " + part.getEFirstName;
//取出参会者中文全名
chiName = part.getCLastName+part.getCFirstName;
//***********************
//取出所在部门跟国家
//***********************
OrganizationsInDB orgsInDB = OrganizationsInDB.getInstance;
//取出所在部门ID
String oid = orgsInDB.getOrganization(pid);
(oid != null) {
Organization org = orgsInDB.locateOrganization(oid);
engOrgName = org.getEName;
chiOrgName = org.getCName;
engCountry = org.getEAddress.getCountry;
chiCountry = org.getCAddress.getCountry;
}
}
}
...
}
  将注释转换为代码让代码足够清楚到可以表示注释?

  我们先看下第个注释:

//存放参会者身上戴牌子所显示信息
public Badge {
...
}
  我们为什么需要这个注释呢?员认为“Badge”这个类名不足以让读代码人清楚这个类作用所以写了这个注释如果我们直接将注释所表达些信息放在类名里面就没有单独写注释必要比如:

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

  将注释转换为变量名

  比如:

public ParticipantInfoOnBadge {
String pid; //参会者ID
String engName; //英文全名
String chiName; //中文全名
String engOrgName; //所在部门英文名称
String chiOrgName; //所在部门中文名称
String engCountry; //部门所在国家中文名称
String chiCountry; //部门所在国家英文名称
...
}
  这里我们将对属性注释转化为属性名比如:

public ParticipantInfoOnBadge {
String participantId;
String participantEngFullName;
String participantChiFullName;
String engOrgName;
String chiOrgName;
String engOrgCountry;
String chiOrgCountry;
...
}
  又如可将对参数注释转化为参数名:

public ParticipantInfoOnBadge {
...
//***********************
//构造
//根据参会者ID从数据库取出该参会者信息
//***********************
ParticipantInfoOnBadge(String pid) {
this.pid = pid;
...
}
}
  可以转化为:

public ParticipantInfoOnBadge {
...
//***********************
//构造
//从数据库取出该参会者信息
//***********************
ParticipantInfoOnBadge(String participantId) {
this.participantId = participantId;
...
}
}
  将注释转换为思路方法部分

  上面构造中有两句注释句我们已经解决了那么还有“从数据库取出该参会者信息”如何处理呢?这句注释描述了该构造如何实现即从数据库取出信息我们可以将这句话转化为:

public ParticipantInfoOnBadge {
...
//***********************
//构造
//***********************
ParticipantInfoOnBadge(String participantId) {
loadInfoFromDB(participantId); //现在看下这个构造内部
我们就能知道这个构造是做什么
}
void loadInfoFromDB(String participantId) {
this.participantId = participantId;
...
}
}
  删掉没用注释

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

public ParticipantInfoOnBadge {
...
//***********************
//构造
//***********************
ParticipantInfoOnBadge(String participantId) {
...
}
}
  就算去掉这些注释我们也能看出来这是个构造这个注释并没什么用处

  什么样类是看代码人最喜欢?那就是简单易看个设计得好能够让人眼看出这个类都有些什么东西明白这个类都做了什么事请如果看这个类时要不停地将屏幕滚来滚去思维还要随屏幕滚动跳转无形中看懂这个类需要花时间就多了

  个屏幕差不多只能显示20行左右代码而这个没用注释下子就占用了3行代码些有用信息反而被挤掉(比如代码)得不偿失还是赶紧移除这个注释吧!

public ParticipantInfoOnBadge {
...
ParticipantInfoOnBadge(String participantId) {
...
}
}
  用思路方法名来表达注释

  还可以将部分代码重构成思路方法用思路方法名来表达注释意思先看看下面这个注释:

void loadInfoFromDB(String participantId) {
this.participantId = participantId;
//***********************
//取得参会者全名
//***********************
ParticipantsInDB partsInDB = ParticipantsInDB.getInstance;
Participant part = partsInDB.locateParticipant(participantId);
(part != null) {
//取得参会者英文全名
engFullName = part.getELastName + ", " + part.getEFirstName;
//取得参会者中文全名
chiFullName = part.getCLastName+part.getCFirstName;
//***********************
//取得参会者所在部门和国家
//***********************
OrganizationsInDB orgsInDB = OrganizationsInDB.getInstance;
//取得参会者被雇佣部门ID
String oid = orgsInDB.getOrganization(participantId);
(oid != null) {
Organization org = orgsInDB.locateOrganization(oid);
engOrgName = org.getEName;
chiOrgName = org.getCName;
engOrgCountry = org.getEAddress.getCountry;
chiOrgCountry = org.getCAddress.getCountry;
}
}
}
  现在我们已经看清这段注释要表达些什么信息要使代码跟注释样清楚我们可以将注释所解释部分代码抽取出来做成个思路方法然后让思路方法名来表达注释意思如果可以我们就不需要额外注释了

void loadInfoFromDB(String participantId) {
this.participantId = participantId;
getParticipantFullNames; //取得参会者全名注意我们已经将注释去掉了
//***********************
//取得参会者所在部门和国家
//***********************
//取得参会者被雇佣部门ID
OrganizationsInDB orgsInDB = OrganizationsInDB.getInstance;
String oid = orgsInDB.getOrganization(participantId);
(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);
(part != null) {
//取得参会者英文全名
engFullName = part.getELastName + ", " + part.getEFirstName;
//取得参会者中文全名
chiFullName = part.getCLastName+part.getCFirstName;
}
}
  此外还有个注释“取得参会者所在部门和国家”也是可以重构在思路方法名里面:

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

  请看下面这两个注释:

public ParticipantInfoOnBadge {
...
void getParticipantFullNames {
ParticipantsInDB partsInDB = ParticipantsInDB.getInstance;
Participant part = partsInDB.locateParticipant(participantId);
(part != null) {
//取得参会者英文全名.
engFullName = part.getELastName + ", " + part.getEFirstName;
//取得参会者中文全名
chiFullName = part.getCLastName+part.getCFirstName;
}
}
}
  员觉得这些代码片段还不够清楚所以还是要用注释来解释它们但这次移除注释时我们会将抽取出来思路方法放到Participant这个类里面而不是ParticipantInfoOnBadge里了

public ParticipantInfoOnBadge {
...
void getParticipantFullNames {
ParticipantsInDB partsInDB = ParticipantsInDB.getInstance;
Participant part = partsInDB.locateParticipant(participantId);
(part != null) {
engFullName = part.getEFullName; //将职责交给do自己也就是Participant
chiFullName = part.getCFullName;
}
}
}
public Participant {
String getEFullName {
getELastName + ", " + getEFirstName;
}
String getCFullName {
getCLastName + getCFirstName;
}
}
  用注释去命名个已经存在思路方法

  请看下面注释这也是本例最后个注释了:

public ParticipantInfoOnBadge {
...
void getOrgNameAndCountry {
OrganizationsInDB orgsInDB = OrganizationsInDB.getInstance;
//取得参会者被雇佣部门ID
String oid = orgsInDB.getOrganization(participantId);
(oid != null) {
Organization org = orgsInDB.locateOrganization(oid);
engOrgName = org.getEName;
chiOrgName = org.getCName;
engOrgCountry = org.getEAddress.getCountry;
chiOrgCountry = org.getCAddress.getCountry;
}
}
}
  的所以要用这个注释“取得参会者被雇佣部门ID”这个思路方法名“getOrganization”还不够清楚所以我们将注释表达信息放在思路方法名里面如下:

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

  看看改进完代码如果让其他人读我们代码现在看懂需要多长时间?而重构的前那个人又需要花多长时间?

public ParticipantInfoOnBadge {
String participantId;
String participantEngFullName;
String participantChiFullName;
String engOrgName;
String chiOrgName;
String engOrgCountry;
String chiOrgCountry;
ParticipantInfoOnBadge(String participantId) {
loadInfoFromDB(participantId);
}
void loadInfoFromDB(String participantId) {
this.participantId = participantId;
getParticipantFullNames;
getOrgNameAndCountry;
}
void getParticipantFullNames {
ParticipantsInDB partsInDB = ParticipantsInDB.getInstance;
Participant part = partsInDB.locateParticipant(participantId);
(part != null) {
participantEngFullName = part.getEFullName;
participantChiFullName = part.getCFullName;
}
}
void getOrgNameAndCountry {
OrganizationsInDB orgsInDB = OrganizationsInDB.getInstance;
String oid = orgsInDB.findOrganizationEmploying(participantId);
(oid != null) {
Organization org = orgsInDB.locateOrganization(oid);
engOrgName = org.getEName;
chiOrgName = org.getCName;
engOrgCountry = org.getEAddress.getCountry;
chiOrgCountry = org.getCAddress.getCountry;
}
}
}
  为什么要删除额外注释?

  为什么要删除额外注释?其实加注释本身是件正确事情注释可以让人更容易地理解代码但问题在于常常没有把代码写清楚所以我们就找了个捷径那就是写上注释注释不够清楚再写上文档这样子可以让人看懂了吧这样造成结果就是没有人愿意去好好地组织代码让代码清楚起来他们觉得加上注释就好了的后代码更新员却常常忘了去更新注释(我们不得不承认这种情况经常发生)过了段时间这些过时注释不仅不能让代码更容易懂反而会误导读代码到了最后我们剩下东西就是:本身就不清晰代码加上些不正确注释

  因此不论什么时候当我们要加注释时我们应该再 3想想:我注释能否转化在代码里面让代码跟注释清晰呢?大多数情况下我们得到答案都是:能个注释都是个改进代码好机会我们不能说注释少代码就是好代码但我们绝对可以说包含太多注释代码绝对不是高质量代码

  思路方法名太长

  请看下面例子:

StockItemsInDB {
//找出所有数目少于10海外存货
StockItem findStockItems {
...
}
}
  如果要将这段注释转为代码原则上我们会改成这样:

StockItemsInDB {
StockItem findStockItemsFromOverseasWithInventoryLessThan10 {
...
}
}


  可惜这个思路方法名实在太长了别急这并不表明我们不能去掉注释相反这是在警告我们代码有问题了有什么问题呢?我们暂且不说先看在这种情况下要如何做呢?现在我们需要判断是:这个系统用户确实只对数目少于10海外存货有兴趣吗?他有没有可能对那些数目少于20海外存货有兴趣?他对本地存货就没兴趣了?或者超过25存货有没有兴趣呢?基于以上考虑我们可以把这里注释转化到参数里面具体如下:



StockItemsInDB {
StockItem findStockItemsWithFeatures(
boolean isFromOverseas,
InventoryRange inventoryRange) {
...
}
}
InventoryRange {
minimumInventory;
maximumInventory;
}
  如果客户真是只对少于10海外存货有兴趣呢?那他肯定有些特殊理由(为什么只是这些条件而不是其他呢?)所以经过了解我们发现海运所花时间很长所以他需要补充这些存货此时我们发现客户真正感兴趣是那些需要补充存货而不仅仅是那些海外数目少于10存货因此我们可以将他真正意思转化在思路方法名和思路方法实现里

StockItemsInDB {
StockItem findStockItemsToReplenish {
StockItem stockItems;
stockItems = findStockItemsFromOverseas;
stockItems = findStockItemsInventoryLessThan10(stockItems);
stockItems;
}
}




0

相关文章

读者评论

发表评论

  • 昵称:
  • 内容: