Как я могу избежать использования исключений для управления потоком? - PullRequest
9 голосов
/ 06 декабря 2008

Мне был поручен проект по разработке набора классов, которые действуют как интерфейс к системе хранения. Требование заключается в том, чтобы класс поддерживал метод get со следующей подписью:

public CustomObject get(String key, Date ifModifiedSince)

По сути, метод должен возвращать CustomObject, связанный с key тогда и только тогда, когда объект был изменен после ifModifiedSince. Если система хранения не содержит key, метод должен возвращать ноль.

Моя проблема заключается в следующем:

Как мне обработать сценарий, в котором ключ существует, но объект не был изменен?

Это важно, потому что некоторые приложения, которые используют этот класс, будут веб-службами и веб-приложениями. Этим приложениям необходимо знать, возвращать ли 404 (не найдено), 304 (не изменено) или 200 (хорошо, вот данные).

Решения, которые я взвешиваю:

  1. Создайте пользовательское исключение, когда система хранения не содержит key
  2. Создайте пользовательское исключение, когда ifModifiedSince терпит неудачу.
  3. Добавить свойство статуса в CustomObject. Требовать звонящего, чтобы проверить собственность.

Я не доволен ни одним из этих трех вариантов. Мне не нравятся варианты 1 и 2, потому что я не люблю использовать исключения для управления потоком. Также мне не нравится возвращать значение, когда я намерен указать, что не было значения .

Тем не менее, я склоняюсь к варианту 3.

Есть ли вариант, который я не рассматриваю? Кто-нибудь испытывает сильные чувства к любому из этих трех вариантов?


Ответы на этот вопрос, перефразированный:

  1. Обеспечить contains метод и требуют, чтобы вызывающий вызывающий его перед звонком get(key, ifModifiedSince), киньте исключение, если ключ не существует, вернуть ноль, если объект не был модифицировано.
  2. Обернуть ответ и данные (если есть) в составном объекте.
  3. Используйте предопределенную константу для обозначения некоторого состояния (UNMODIFIED, KEY_DOES_NOT_EXIST).
  4. Абонент реализует интерфейс для используется в качестве обратных вызовов.
  5. Дизайн отстой.

Почему я не могу выбрать ответ № 1

Я согласен, что это идеальное решение, но это я уже (неохотно) отменил. Проблема этого подхода заключается в том, что в большинстве случаев, когда эти классы будут использоваться, внутренняя система хранения данных будет удаленной системой стороннего производителя, например Amazon S3. Это означает, что метод contains потребует обратной передачи в систему хранения, за которой в большинстве случаев последует повторная передача в обе стороны. Поскольку это будет стоить и времени, и денег , это не вариант.

Если бы не это ограничение, это был бы наилучший подход.

(Я понимаю, что не упомянул этот важный элемент в вопросе, но я пытался держать его кратким. Очевидно, это было актуально.)


Вывод:

После прочтения всех ответов я пришел к выводу, что в этом случае наилучшим подходом является обертка. По сути, я буду имитировать HTTP с метаданными (заголовками), включая код ответа, и телом содержимого (сообщение).

Ответы [ 11 ]

0 голосов
/ 06 декабря 2008

Если это приемлемо, вы можете вернуть усиленный CustomObject (обертка), который содержал значения, которые представляли объект и состояние его модификации, если таковые имеются, и т. Д.

...