重构两个代码

时间:2014-01-27 09:10:05

标签: java refactoring

我的项目需要将两种类型的文本数据解析为数据库。

一种格式是这样的:

 <lineNumber>19</lineNumber>
 <begin>
 2013-08-15,2013-08-15,pek001,123456,08654071,CANX,,,,,,011  
 <end>

一个就是那个

<lineNumber>27</lineNumber>
 <begin>
 2012-11-02,08683683,pek001,00001234,vvip,1
 <end>

两个文本的区别在于开始和结束标记。 所以我们的解析代码出来了: 第一个是:

         inputStreamReader = new InputStreamReader(new   FileInputStream(FileOne),"gbk");  --different place
         br=new BufferedReader(inputStreamReader);
     lineNumber = 0;
         boolean isDataContent = false;

     while (br.ready()) {
            String  line = br.readLine();
            if(line == null){
                continue;
            }
            if(line.contains("<lineNumber>"))
            {

                try {
                    lineNumber = Integer.parseInt(StringTools.getDigitalInString(line));
                } catch (NumberFormatException e) {
                    log.error("there is no lineNumber。");
                }
                continue;
            }

            if(line.trim().equals("<begin>"))
            {
                isDataContent = true;
                continue;  
            }

            if(line.trim().equals("<end>"))
            {
                break;    
            }

            if(isDataContent)
            {                  
                 insertFirstToDatabase(line,vo);  --just this is different.
            }


        }

第二个是:

  inputStreamReader = new InputStreamReader(new   FileInputStream(FileTwo),"gbk"); 
   --different place
        br=new BufferedReader(inputStreamReader);
        lineNumber = 0;
        boolean isDataContent = false;

   while (br.ready()) {
            String  line = br.readLine();
            if(line == null){
                continue;
            }
            if(line.contains("<lineNumber>"))
            {

                try {
                    lineNumber = Integer.parseInt( StringTools.getDigitalInString(line));
                } catch (NumberFormatException e) {
                    log.error("there is no lineNumber");
                }
                continue;
            }

            if(line.trim().equals("<begin>"))
            {
                isDataContent = true;
                continue;  
            }

            if(line.trim().equals("<end>"))
            {
                break;     
            }

            if(isDataContent)
            {

                          insertSecondToDatabase(line,vo);  --only this is different.
            }
        }

这两段代码在两个不同的服务代码中。我怎样才能重构这个重复代码?这样每个地方只调用一个相同的函数来检查lineNumber。

4 个答案:

答案 0 :(得分:0)

在类中包含重复的代码,其他类继承(继承)或包含(组合)的副本。或者,您甚至可以在实用程序类中将其设置为静态方法。

答案 1 :(得分:0)

您的代码在单个语句之前是相同的,并且没有显示您如何确定应该执行哪些代码序列,而只是将该分支移动到if (isDataContent)

// copy/paste from your own, change the if to:
if(isDataContent) {
    if (flagFirst) {
        insertFirstToDatabase(line,vo);  --just this is different.
    } else {
        insertSecondToDatabase(line,vo);  --only this is different.
    }
}

其中flagFirst是布尔变量或布尔表达式,用于确定应该执行哪些插入。

答案 2 :(得分:0)

您可以添加'kind'参数来选择有用的插入方法,如下所示:

public void process(int kind) {

    ....

    while (br.ready()) {
        String  line = br.readLine();
        if(line == null){
            continue;
        }
        if(line.contains("<lineNumber>"))
        {

            try {
                lineNumber = Integer.parseInt( StringTools.getDigitalInString(line));
            } catch (NumberFormatException e) {
                log.error("there is no lineNumber");
            }
            continue;
        }

        if(line.trim().equals("<begin>"))
        {
            isDataContent = true;
            continue;  
        }

        if(line.trim().equals("<end>"))
        {
            break;     
        }

        if(isDataContent)
        {
            if (kind == 1) {
                insertFirstToDatabase(line,vo);  --just this is different.
            }
            if (kind == 2) {
                insertSecondToDatabase(line,vo);  --only this is different.
            }
        }
    }

}

答案 3 :(得分:0)

2件事:

  1. 重复的代码? - 在实用程序类中放入静态方法
  2. 如何区分dataContent? -
    一世。这可以在根据字段的顺序解析行时确定 (或)
    II。静态方法的被调用者可以通过发送标志来确定相同的内容。但这不是好设计。您在实用程序方法中放置了太多的实现,即2个行为 (或)
    III。让静态方法解析XML并仅将行详细信息返回给被调用者。让被叫者处理它喜欢的。第一个被调用者可能只想打印,第二个被调用者可能想放入db。
  3. 所以,在这里,

        public static LineDetails parseXML(String filename)
        {
    
        inputStreamReader = new InputStreamReader(new   FileInputStream(new File(filename)); 
    
                br=new BufferedReader(inputStreamReader);
            lineNumber = 0;
            boolean isDataContent = false;
            LineDetails lineDetails = new LineDetails();
    
       while (br.ready()) {
                String  line = br.readLine();
                if(line == null){
                    continue;
                }
                if(line.contains("<lineNumber>"))
                {
    
                    try {
                        lineNumber = Integer.parseInt( StringTools.getDigitalInString(line));
                    } catch (NumberFormatException e) {
                        log.error("there is no lineNumber");
                    }
                    lineDetails.setLineNumber(lineNumber);
                    continue;
                }
    
                if(line.trim().equals("<begin>"))
                {
                    isDataContent = true;
                    continue;  
                }
    
                if(line.trim().equals("<end>"))
                {
                    break;     
                }
    
                if(isDataContent)
                {
                 // parse line
                 lineDetails.setLine(line);
                }
            }
      return lineDetails;
    }
    

    public class LineDetails
    {
     private int lineNumber=0;
     private String line="";
     // getters setters
    }
    

    //First callee
    methodA()
    {
      LineDetails lineDetails = parseXML(filename);
      if(lineDetails!=null && lineDetails.getLineNumber==19 && lineDetails.getLine()!=null && !lineDetails.getLine.equals(""))
      { 
        insertFirstToDatabase(line); 
      }
    }
    
    
    //Second callee
    methodB()
    {
      LineDetails lineDetails = parseXML(filename);
      if(lineDetails!=null && lineDetails.getLineNumber==27 && lineDetails.getLine()!=null && !lineDetails.getLine.equals(""))
      { 
        insertSecondToDatabase(line); 
      }
    }