【问题标题】:Where to place constant attributes?在哪里放置常量属性?
【发布时间】:2017-07-05 11:05:33
【问题描述】:

我想用java编写干净的代码,但我很不安全将我的属性放在哪里。

我经常无法决定,是将它们放在类的顶部、构造函数中还是直接放在方法中。那里有一些规则吗?对我来说唯一的逻辑是,当这些属性用于多个方法时,将属性放在类的顶部。

你能用干净的代码来评估这段代码吗?我应该将常量货币属性放在构造函数中吗?我也可以将一些类属性放在方法中吗?感谢您的建议

public class CsvFileReader  {
    private SimpleDateFormatStringToDate formatter = new SimpleDateFormatStringToDate();
    private IataExchangeRateDataSet exchangeRateDataSet= new IataExchangeRateDataSet();
    private final String SEMICOLON_DELIMITER = ";";

    // Currency attributes index
    private final int CURRENCY_VALUE = 1;
    private final int CURRENCY_ISO_CODE = 2;
    private final int CURRENCY_PERIOD_START = 3;
    private final int CURRENCY_PERIOD_END = 4;

    public CsvFileReader(IataExchangeRateDataSet exchangeRateDataSet) {
        this.exchangeRateDataSet = exchangeRateDataSet;
    }

    public void readCsvFile(String fileName, final int maxLengthOfColumn) {

        BufferedReader fileReader = null;
        try {
            String line = "";
            fileReader = new BufferedReader(new FileReader(fileName));

            while ((line = fileReader.readLine()) != null) {

                String[] tokens = line.split(SEMICOLON_DELIMITER);

                //TODO: Noch auf Vollständigkeit der Zeile, Korrektheit der Datumsformate und ähnliches überprüfen
                if ( tokens.length== maxLengthOfColumn && DateFormat.checkDateFormat(tokens[CURRENCY_PERIOD_START]) && DateFormat.checkDateFormat(tokens[CURRENCY_PERIOD_END])) {

                    //format currency value in csv
                    tokens[CURRENCY_VALUE]=tokens[CURRENCY_VALUE].replace(",", ".");

                    IataExchangeRateData iataExchangeRateData = new IataExchangeRateData(
                            new BigDecimal(tokens[CURRENCY_VALUE]), tokens[CURRENCY_ISO_CODE],
                            formatter.parseStringToDate(tokens[CURRENCY_PERIOD_START]),
                            formatter.parseStringToDate(tokens[CURRENCY_PERIOD_END]));

                    exchangeRateDataSet.getExchangeRateDataSet().add(iataExchangeRateData);
                }
            }
        }

        catch (Exception e) {
            System.out.println("Error in CsvFileReader");
            e.printStackTrace();
        } finally {
            try {
                fileReader.close();
            } catch (IOException e) {
                System.out.println("Error while closing fileReader !!!");
                e.printStackTrace();
            }
        }
    }
}

【问题讨论】:

    标签: java coding-style refactoring


    【解决方案1】:
    1. 如果任何属性用于方法内的计算或操作,则仅在方法内使用该属性。
    2. 如果使用了任何属性以使任何方法都可以引用它,则在所有方法的顶部使用它。
    3. 如果任何属性不依赖于类,例如计算特定对象的线程数,则通过将其设为静态,将其用作类变量。

    【讨论】:

      【解决方案2】:

      干净的代码问题通常会引发争论,有些正确,有些则不太正确。但是我已经感受到了你现在对常量所做的方式,并且我使用它们的方式就像你在代码中所做的那样,即在构造函数的正上方。但最近,我把它们放在interface 中。有点像这样的

      public interface CurrencyConstants {
          int CURRENCY_VALUE = 1;
          int CURRENCY_ISO_CODE = 2;
          int CURRENCY_PERIOD_START = 3;
          int CURRENCY_PERIOD_END = 4;
      }
      

      然后我只需导入接口并像这样使用常量..

      CurrencyConstants.CURRENCY_VALUE
      

      如果常量在多个类中使用,这会有所帮助。干杯!

      【讨论】:

      • 感谢您的评论。在设置文件名的位置方面,您有什么建议?我应该在这个类中设置具体文件名,还是应该在 MainClass 中设置具体文件名,然后从那里将文件名提供给这个类的方法 readCsvFile(就像现在这个版本一样)。
      • @Peter 这个版本适合文件名(MainClass 中的文件名)。