簡體   English   中英

重構csv讀取,解析和對象初始化代碼片段

[英]Refactoring csv reading, parsing and object initializing code snippet

我嘗試重構一些舊代碼,用於從CSV文件中讀取數據,解析每一行並初始化CSV文件中每一行的對象實例,並將每個對象保存在列表中。
我也嘗試學習SOLID原理並應用它們。

至於單一責任原則我有一個CsvReader類,它有一個方法read()
我認為這種方法有太多的責任
讀一條線(1),
解析它(2),
初始化Row的新對象實例(3)
最后將所有這些存儲在列表中(4)。

我也不喜歡我在read方法(5)中新建它。

我應該如何重構它? 這五點是真正的問題,還是我過分擔心它,不應該試圖在任何地方都遵循SRP。 似乎到處使用它是不合理的。

public void read() {

    String thisLine = null;
    String[] splitted = null;
    List<Row> rows = new ArrayList<>();

    try {
        BufferedReader br = new BufferedReader(new FileReader(new File(
                "input.txt")));
        while ((thisLine = br.readLine()) != null) {
            splitted = thisLine.split(",");
            Row row = new Row(splitted[0], splitted[1]);
            rows.add(row);
        }
        br.close();
    } catch (Exception e) {
        e.printStackTrace();
    } 
}

但是,我不確定以下是否違反了SRP。 我相信新的更多是額外的責任。

Row = new Row(splitted[0],splitted[1]);

這就是我自己重構的方法。 我會將行拆分放入一個名為Parser的單獨類中。 但我不確定Parser應該如何互動。 Parser本身應該初始化一個Row實例並返回它嗎? 但是后來我再次將行拆分為Parser類,但似乎我仍然卡住了,因為Parser類必須拆分並且還要新建一個Row實例。 這是我重構的代碼(CsvReader類只有一個名為read()的方法):

public void read(List<Row> row) {

    String thisLine = null;

    try {
        BufferedReader br = new BufferedReader(new FileReader(new File(
                "input.txt")));
        while ((thisLine = br.readLine()) != null) {
            //splitted = thisLine.split(",");
            Row row = Parser.parse(thisLine);
            //Row row = new Row(splitted[0], splitted[1]);
            rows.add(row);
        }
        br.close();
    } catch (Exception e) {
        e.printStackTrace();
    } 
}

而Parser類將是:

public class Parser {

    static String[] splitted = null;

    static Row parse(String inputLine) {
        splitted = inputLine.split(",");
        return new Row(splitted[0], splitted[1]);
    }

}

我認為靜態Parser.parse方法應該只解析而不是新建一個Row類的實例。

可能是這樣的。

一個用於解析文件的類:

public class Parser {

    private final String file;
    private final LineParser lineParser;

    public Parser(final String file) {
        this.file = file;
        lineParser = new LineParser();
    }

    public ArrayList<Row> parse() {
        String thisLine = null;
        ArrayList<Row> rows=new ArrayList<Row>();
        try {
            BufferedReader br = new BufferedReader(new FileReader(file));
            while ((thisLine = br.readLine()) != null) {
                Row row = lineParser.parse(thisLine);
                rows.add(row);
            }
            br.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return rows;
    }
}

解析該行的其他類:

public class LineParser {
    public Row parse(final String line) {
        String[] splitted = line.split(",");
        return new Row(splitted[0], splitted[1]);
    }
}

盡量避免使用靜態方法。

  1. 沒有理由創建一個Parser類來定義parse()方法。 將該parse()方法放在CsvReader類中。 它是pricate方法的目的:由類的其他方法在內部使用。
  2. 然后一個好的做法是提供一個InputStream作為read()方法的參數。 這樣,如果將來你想使用該方法來讀取文件(例如URL或套接字)的其他內容,則無需更改。
  3. 我可以建議你的read方法拋出異常嗎? 如果在操作過程中出現錯誤,最好收到通知。 使用例外,您可以在更高級別(例如在GUI中)執行此操作。
  4. 最后,當您打開Reader時,您應該依賴AutoCloseable機制。

     public class CsvReader { public List<Row> read(final InputStream in) throws IOException { final List<Row> rows = new ArrayList<>(); try (final BufferedReader br = new BufferedReader( new InputStreamReader(in))) { String line = br.readLine(); while (line != null) { rows.add(parse(line)); line = br.readLine(); } } return rows; } private Row parse(final String inputLine) { final String[] splitted = inputLine.split(","); return new Row(splitted[0], splitted[1]); } } 

作為旁注:您是否真的需要使用Row類來存儲數據? String數組在這里可以很好地工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM