清洁代码 - 以下划线开头的受保护方法的目的是什么?

时间:2014-07-25 16:33:05

标签: java

我正在阅读鲍勃叔叔的清洁代码。在第16章中,该书展示了如何重构一个例子。有一部分我无法达到以这种方式写作的目的。

  • 在这里使用protected关键字的目的是什么?
  • 为什么像_getMinimumYear()这样的方法以下划线开头?
  • 为什么要使用一对具有相同名称的方法而不是像public abstract int getMinimumYear();
  • 这样的抽象方法

public abstract class DayDateFactory {

    private static DayDateFactory factory = new SpreadsheetDateFactory();
    public static void setInstance(DayDateFactory factory) {
        DayDateFactory.factory = factory;
    }

    protected abstract DayDate _makeDate(int ordinal);
    protected abstract DayDate _makeDate(int day, Month month, int year);
    protected abstract DayDate _makeDate(int day, int month, int year);
    protected abstract DayDate _makeDate(java.util.Date date);
    protected abstract int _getMinimumYear();
    protected abstract int _getMaximumYear();

    public static DayDate makeDate(int ordinal) {
      return factory._makeDate(ordinal);
    }

    public static DayDate makeDate(int day, Month month, int year) {
      return factory._makeDate(day, month, year);
    }

    public static DayDate makeDate(int day, int month, int year) {
      return factory._makeDate(day, month, year);
    }

    public static DayDate makeDate(java.util.Date date) {
      return factory._makeDate(date);
    }

    public static int getMinimumYear() {
      return factory._getMinimumYear();
    }

    public static int getMaximumYear() {
      return factory._getMaximumYear();
    }
}

    public class SpreadsheetDateFactory extends DayDateFactory {
    public DayDate _makeDate(int ordinal) {
    return new SpreadsheetDate(ordinal);
    }

    public DayDate _makeDate(int day, Month month, int year) {
    return new SpreadsheetDate(day, month, year);
    }

    public DayDate _makeDate(int day, int month, int year) {
    return new SpreadsheetDate(day, month, year);
    }

    public DayDate _makeDate(Date date) {
    final GregorianCalendar calendar = new GregorianCalendar();
    calendar.setTime(date);
    return new SpreadsheetDate(
    calendar.get(Calendar.DATE),
    Month.fromInt(calendar.get(Calendar.MONTH) + 1),
    calendar.get(Calendar.YEAR));
    }

    protected int _getMinimumYear() {
    return SpreadsheetDate.MINIMUM_YEAR_SUPPORTED;
    }

    protected int _getMaximumYear() {
    return SpreadsheetDate.MAXIMUM_YEAR_SUPPORTED;
    }
}

1 个答案:

答案 0 :(得分:4)

Python使用leading underscore来表示该方法是内部的,而不是与外部世界签订任何合同的一部分。好像鲍勃叔叔正在做类似的事情,除了这里当然没有工具支持。随着时间的推移,他将注意力从为熟悉C ++的观众的写作转移到为熟悉脚本语言的人写作;他可能期望他的读者对Python或Ruby有足够的熟悉来识别这种事情。所以他使用的是惯例,而不是Java。

鲍勃叔叔正在对他介绍的工厂实例方法进行强调。看起来他并不打算公开这些方法(它们只对子类和同一个包中的类可见),他工厂的子类必须实现它们,但是包外的代码不会看到它们。他还希望对工厂方法使用与公共静态方法相同的名称,但他需要一个约定来保持它们的正确性。我认为他正试图尽量减少将内部工厂的实例方法与暴露的静态方法混淆的可能性,而不为工厂引入单独的接口。