Java: динамические ограничения типа - PullRequest
0 голосов
/ 08 ноября 2018

В настоящее время я работаю над обработчиком протокола для моего проекта на Java. Я пытаюсь создать поддерживаемый и расширяемый API, то есть я не хочу просто жестко кодировать поддерживаемые типы значений.

Я начал проектировать «обработчик протокола», который с заданным значением (поддерживаемого типа) может кодировать это значение в соответствии со спецификацией протокола, не заботясь о деталях процесса перевода.

Различные типы значений, например Строки или целые числа обязательно имеют разные процессы кодирования, но я не хочу, чтобы клиенты беспокоились о хранении ссылок на разные объекты для каждого возможного типа, который им может понадобиться кодировать - как я сказал, я не хочу, чтобы они беспокоились о деталях.

До сих пор я определил «универсальный» класс DynamicHandler, который поддерживает коллекцию StaticHandlers, поддерживающих «определенный» тип:

class DynamicHandler
{
  Map<Class, StaticHandler> handlers;

  <T> void handle(T value)
  {
    if(handlers.containsKey(value.class))
      handlers.get(value.getType()).handle(value);
  }

  void <T> register(StaticHandler<T> handler)
  {
    handlers.put(T.class, handler);
  }
}

Идея этого класса заключается в том, что клиент просто передает значение, которое он хочет кодировать, методу handle, и DynamicHandler ищет и делегирует StaticHandler.

interface StaticHandler<T>
{
  void handle(T value);
}

Вот пример клиента, который использует эту систему:

class StringHandler implements StaticHandler<String>
{
  void handle(String value)
  {
    ...
  }
}

DynamicHandler handler = new DynamicHandler();
handler.register(new StringHandler());
handler.handle("Hello World!");

У меня есть два вопроса, на которые я пытаюсь найти ответ самостоятельно:

  1. В методе DynamicHandler.register как я могу получить тип T, не имея экземпляра T?
  2. Можно ли реализовать тип DynamicHandler в виде java.util.Map, чтобы максимизировать совместимость с любыми сторонними кодами, которые клиенты могут использовать для создания или другой обработки таких объектов?

Редактировать: Поскольку DynamicHandler по сути является картой, хотя и с некоторыми общими хитростями, возможно ли реализовать ее следующим образом: DynamicHandler implements java.util.Map<...,...> (я не совсем уверен, какие типы ключей и значений должны быть здесь).

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

Ответы [ 2 ]

0 голосов
/ 08 ноября 2018

Если null значения не обрабатываются и что оно разработано так, что никогда не будет никакого значения, принадлежащего нескольким классам, тогда вы можете сделать это:

public class DynamicHandler {
    Map<Class, StaticHandler> handlers;

    public <T> void handle(T value) {
        if(value != null) {
            handlers.entrySet()
                    .stream()
                    .filter(entry -> 
                        entry.getKey().isInstance(value))
                    .findAny()
                    .ifPresent(entry ->
                        entry.getValue().handle(value));
        }
    }

    public void <T> register(StaticHandler<T> handler) {
        handlers.put(handler.getHandlingClass(), handler);
    }
}


interface StaticHandler<T>
{
    void handle(T value);
    Class<T> getHandlingClass();
}

public class StringHandler implements StaticHandler<String> {
    @Override public void handle(String value) {
        ...
    }
    @Override public final Class<String> getHandlingClass() {
        return String.class;
    }
}
0 голосов
/ 08 ноября 2018
  1. В классе DynamicHandler как я могу получить тип T без экземпляра T?

Обычное решение для этого - передать ему объект Class:

 void <T> register(StaticHandler<T> handler, Class<T> clazz)
  {
    handlers.put(clazz, handler);
  }

Так же, как один пример этого в широко используемой библиотеке: Gson делает что-то похожее для регистрации сериализаторов JSON для определенных типов с GsonBuilder.registerTypeHierarchyAdapter

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