Как избежать необходимости объявлять параметры типа для всех зависимостей в универсальном классе

#java #oop #generics #abstract-class

#java #ооп #общие #абстрактный класс

Вопрос:

У меня есть несколько вопросов по следующей проблеме. Кто-нибудь может помочь?

Вопрос в том,:

  1. Является ли следующий дизайн хорошим дизайном?
  2. Если да, то как улучшить его, чтобы избежать объявления параметров типа в классе ввода.

Проблема

Предполагая, что я работаю над классами для обработки запроса и извлечения данных для ответа. У меня есть

  • обработчик запроса — который вызывает помощник запроса для извлечения данных
  • помощник по запросам — вызывает конструктор запросов для построения запроса и вызова базы данных с его помощью.
  • конструктор запросов — создает запрос.

В моем случае для каждого отдельного запроса требуется другой возвращаемый тип. Помощник по запросу также возвращает другой тип для другого запроса. В этом контексте я разрабатываю его с помощью универсального класса и абстрактного класса.

 abstract class RequestHandler<T1, T2> {
  QueryHelper<T2> helper;

  T1 doGet(Request request) {
    ...
    helper.callDatabase();
    return customLogic();
  }

  abstract T1 customLogic()
}

abstract class QueryHelper<T2> {
  QueryBuilder builder;

  T2 callDatabase() {
    ...
    client.call(builder.buildQuery());
    return customLogic(...);
  }

  abstract T2 customLogic()
}

abstract class QueryBuilder {

  abstract Query buildQuery();
}
  

С помощью этого дизайна я могу обрабатывать разные запросы с разными подклассами. например, для запроса get product A у меня есть

 class ProductAQueryBuilder extends QueryBuilder {
  
  @Override
  Query buildQuery() {
    ...
  }
}

class ProductAQueryHelper extends QueryHelper<TypeA> {
  QueryBuilder builder;

  ProductAQueryHelper(ProductAQueryBuilder builder) {
    this.builder = builder;
  }

  @Override
  TypeA customLogic()
}

class ProductARequestHandler extends RequestHandler<TypeB, TypeA> {
  QueryHelper<TypeA> helper;

  ProductARequestHandler(ProductAQueryHelper helper) {
    this.helper = helper;
  }
  
  @Override
  TypeB customLogic()
}

  

Это кажется прекрасным, потому что я упростил проблему. На самом деле, у меня есть более одного параметра типа для RequestHandler и QueryBuilder, что заставляет меня объявлять множество параметров типа в RequestHandler<T1, T2, T3, T4 …>. Это беспокоит меня, потому что я должен объявлять все параметры типа для цепочки зависимостей. Есть ли способ улучшить это?

Спасибо!

Комментарии:

1. Действительно ли типы T1, T2, T3, T4 … независимы? Или, например, T3 может быть выражен как Collection<T1>? Ваш пример RequestHandler показывает, что T1 и T2 могут иметь сильную корреляцию.

2. Привет, Ральф, спасибо за комментарий! T1, T2, T3, T3 действительно независимы — спасибо, что напомнили мне об этом. Я посмотрю, смогу ли я уменьшить некоторые из них. Просто хочу быстро проверить (я не очень опытен в ООД), является ли этот тип дизайна надежным шаблоном? или мне поискать альтернативный вариант?