"Передача аргументов" через ThreadLocal хорошо? - PullRequest
1 голос
/ 18 апреля 2011

Я создаю сетевую библиотеку Java и приложение, которое ее использует.Библиотека состоит из:

  • Интерфейс PacketSocket, который имеет методы для отправки и получения пакетов байтов.
  • Две его реализации, одна по TCP и одна по UDP.
  • Класс ObjectConnection, который построен поверх PacketSocket и обрабатывает сериализацию объектов в байтовые пакеты.

Приложение использует RequestConnection поверх UDPPacketSocket.Реализация UDPPacketSocket уникальна тем, что поддерживает указание для каждого пакета, должна ли быть гарантирована доставка.Я хотел бы иметь возможность использовать из приложения, но нет никакого пути через интерфейсы ObjectConnection и PacketSocket.

Конечно, я мог бы добавить логический гарантированный параметр к применимым методам в этих интерфейсах, но затемВ конце концов, я (когда будет больше реализаций PacketSocket) пришлось бы добавить гораздо больше параметров, которые относятся только к определенным реализациям и игнорируются другими.

Вместо этого я решил, что могу сделать это со статическим потокомлокальное свойство UDPPacketSocket, например, так:

class Application {

  public void sendStuff() {

    // is stored in a ThreadLocal, so this code is still thread-safe
    UDPPacketSocket.setGuaranteed(true);

    try {
       myObjCon.send(...);
    } finally {
       // ... restore old value of guaranteed
    }

  }
}

Что вы думаете о таком подходе?

Ответы [ 4 ]

3 голосов
/ 18 апреля 2011

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

Я бы избежал этого, если бы ты мог. Лучшим вариантом будет иметь следующее, если возможно

 myObjCon.sendGuaranteed(...);
0 голосов
/ 18 апреля 2011

, поскольку мы знаем, что это UDP, мы можем де-абстрагировать слои и получить доступ к конкретному материалу

( (UDPSocket)connection.getSocket() ).setGuaranteed(true);
0 голосов
/ 18 апреля 2011

Я бы порекомендовал какой-то параметр "характеристики производительности", может быть, что-то вроде экземпляра Properties. тогда каждый impl может использовать свои собственные произвольные свойства (например, «гарантировано» для вашего текущего impl). Обратите внимание, что вы можете избежать анализа строк, используя методы объекта в свойствах (например, get() вместо getProperty()) или используя прямой экземпляр Map. тогда ваши значения могут быть истинными объектами (например, логическое значение).

0 голосов
/ 18 апреля 2011

Я согласен, что это безобразный хак.Это будет работать, но вы можете сожалеть, что сделали это.

Я бы справился с этим, используя объект Properties для передачи различных параметров реализации PacketSocket.Если это неприятно, определите интерфейс PacketSocketParameters с иерархией классов реализации для различных типов PacketSocket.

...