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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了清洁代码 - 以下划线开头的受保护方法的目的是什么?相关的知识,希望对你有一定的参考价值。

我正在阅读鲍勃叔叔的清洁代码。在第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;
    

答案

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

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

以上是关于清洁代码 - 以下划线开头的受保护方法的目的是什么?的主要内容,如果未能解决你的问题,请参考以下文章

为啥只有 clone 和 finalize 是对象类中的受保护方法?

无法访问派生类中的受保护方法

超类中的受保护方法在不同包中的子类中是不是可见? [复制]

创建类的受保护构造函数有啥好处和坏处

绕过错误 C2248“无法访问在类中声明的受保护成员”的有效方法

为啥我不能在同一类的受保护方法中调用方法[重复]