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

jay*_*917 4 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

Nat*_*hes 5

Python 使用前导下划线表示该方法是内部方法,而不是与外界的任何契约的一部分。鲍勃叔叔似乎也在做类似的事情,只不过这里当然没有工具支持。随着时间的推移,他的注意力从为熟悉 C++ 的读者写作转向为熟悉脚本语言的读者写作。他可能希望他的读者对 Python 或 Ruby 足够熟悉,能够认识到这类事情。所以他使用的是一种约定,而不是 Java 约定。

这里鲍勃叔叔在他引入的工厂实例方法上划了下划线。似乎他并不打算公开这些方法(它们仅对子类和同一包中的类可见),他的工厂的子类必须实现它们,但包外部的代码将看不到它们。他还想对工厂方法使用与公共静态方法相同的名称,但他需要一个约定来保持它们的一致性。我认为他试图最大限度地减少内部工厂的实例方法与公开的静态方法混淆的可能性,而不为工厂引入单独的接口。