Скрытие параметров типа, которые являются деталями реализации - PullRequest
0 голосов
/ 26 ноября 2018

У меня есть класс, у которого есть некоторые параметры типа, которые не являются деталями реализации, а некоторые являются.

Как лучше всего обращаться с параметрами типа, которые не должны быть частью общедоступного API, не прибегая кнепроверенные приведения?

У меня есть класс, созданный строителем, который выбирает правильных помощников.В моем случае, помощник знает, как выполнять массовое чтение / запись между объектами, похожими на буфер.

/**
 * @param <T> a type parameter that end users of PublicClass cannot ignore.
 * @param <X> has a specific relationship to T, but
 *     is an artifact of how PublicClass is implemented.
 */
public class PublicClass<T> {
  // This constructor is called from a builder.
  // The builder just returns
  //     new PublicClass<>(aHelper, someMutableState)
  // <X> is inferred from the choice of parameters.      
  <X> PublicClass(
      Helper<T, X> helper,
      StatefulInternalObject<T, X> someMutableState) {
    ...
  }

  ...
}

Итак, есть открытый класс и публичный компоновщик, а также некоторые классы деталей реализации частного пакета.

Я не хочу показывать <X> клиентам, но мой помощник и мои объекты с состоянием должны взаимодействовать способами, которые зависят от <X>, и помощник преобразует типы, которые используют <T>, в типы, которые используют<X>, поэтому использование непроверенных приведений с участием <X> сделает реализацию PublicClass хрупкой.

Я могу создать еще один скрытый класс, который имеет оба набора параметров типа, а затем сделать мой открытый API просто перенаправленным в этот класс:

public class PublicCLass<T> {
  private final class TypedImpl<T, ?> typeSafeImplementation;

  <X> PublicClass(
      Helper<T, X> helper,
      StatefulInternalObject<T, X> someMutableState) {
    typeSafeImplementation = new TypedImpl<>(
        helper, someMutableState);
  }

  // Public API just forwards to an internal
  // implementation class.
  public SomeType0 someMethod(SomeType1 x) {
    return typeSafeImplementation(x);
  }

  ...
}

Есть ли лучший способ, который не требует этих мелких методов пересылки?

...