服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

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

摘要:
本文作者通过实例介绍了敏捷开发的必要技巧:将注释转为代码. 

示例 

   这是一个会议管理系统. 在会议中,每个参会者都会戴一个牌子,这牌子上面有这个参会者的信息(比如姓名之类的).在这个系统中,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(); 
               }
            }
         }
         ...     } 

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

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

    //存放参会者身上戴的牌子所显示的信息.     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; //部门所在国家的英文名称 
       ...     } 

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

    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; 
            ... 
        } 
     } 

比如: 

    public class participantinfoonbadge { 
        ... 
        //***********************
         //构造函数. 
        //从数据库取出该参与者的信息. 
       //*********************** 
        participantinfoonbadge(string participantid) {
            this.participantid = participantid; 
            ... 
        }
      } 

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

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

    public class participantinfoonbadge { 
        ... 
        //*********************** 
        //构造函数. 
        //*********************** 
        participantinfoonbadge(string participantid) {
            loadinfofromdb(participantid);//现在,看一下这个构造函数内部,我们就能知道这个构造函数是做什么了吧.
         }
         void loadinfofromdb(string participantid) {
            this.participantid = participantid; 
            ...
         }
      } 

删掉没用的注释

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

    public class participantinfoonbadge {
         ... 
        //*********************** 
        //构造函数.
         //*********************** 
        participantinfoonbadge(string participantid) {
             ...
         }
      } 

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

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

        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();
             }
         }

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

        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(); 
            }
         } 

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

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

    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(); 
        }
      } 

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

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

    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"取得不够清楚. 所以,我们将注释表达的信息,放在这个方法名里面: 

    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

扫描关注微信公众号