Мне был поручен проект по разработке набора классов, которые действуют как интерфейс к системе хранения. Требование заключается в том, чтобы класс поддерживал метод get со следующей подписью:
public CustomObject get(String key, Date ifModifiedSince)
По сути, метод должен возвращать CustomObject
, связанный с key
тогда и только тогда, когда объект был изменен после ifModifiedSince
. Если система хранения не содержит key
, метод должен возвращать ноль.
Моя проблема заключается в следующем:
Как мне обработать сценарий, в котором ключ существует, но объект не был изменен?
Это важно, потому что некоторые приложения, которые используют этот класс, будут веб-службами и веб-приложениями. Этим приложениям необходимо знать, возвращать ли 404 (не найдено), 304 (не изменено) или 200 (хорошо, вот данные).
Решения, которые я взвешиваю:
- Создайте пользовательское исключение, когда
система хранения не содержит
key
- Создайте пользовательское исключение, когда
ifModifiedSince
терпит неудачу.
- Добавить свойство статуса в CustomObject. Требовать звонящего, чтобы проверить собственность.
Я не доволен ни одним из этих трех вариантов. Мне не нравятся варианты 1 и 2, потому что я не люблю использовать исключения для управления потоком. Также мне не нравится возвращать значение, когда я намерен указать, что не было значения .
Тем не менее, я склоняюсь к варианту 3.
Есть ли вариант, который я не рассматриваю? Кто-нибудь испытывает сильные чувства к любому из этих трех вариантов?
Ответы на этот вопрос, перефразированный:
- Обеспечить
contains
метод и требуют, чтобы вызывающий вызывающий его
перед звонком get(key,
ifModifiedSince)
, киньте
исключение, если ключ не существует,
вернуть ноль, если объект не был
модифицировано.
- Обернуть ответ и данные (если есть)
в составном объекте.
- Используйте предопределенную константу для обозначения некоторого состояния (
UNMODIFIED, KEY_DOES_NOT_EXIST
).
- Абонент реализует интерфейс для
используется в качестве обратных вызовов.
- Дизайн отстой.
Почему я не могу выбрать ответ № 1
Я согласен, что это идеальное решение, но это я уже (неохотно) отменил. Проблема этого подхода заключается в том, что в большинстве случаев, когда эти классы будут использоваться, внутренняя система хранения данных будет удаленной системой стороннего производителя, например Amazon S3. Это означает, что метод contains
потребует обратной передачи в систему хранения, за которой в большинстве случаев последует повторная передача в обе стороны. Поскольку это будет стоить и времени, и денег , это не вариант.
Если бы не это ограничение, это был бы наилучший подход.
(Я понимаю, что не упомянул этот важный элемент в вопросе, но я пытался держать его кратким. Очевидно, это было актуально.)
Вывод:
После прочтения всех ответов я пришел к выводу, что в этом случае наилучшим подходом является обертка. По сути, я буду имитировать HTTP с метаданными (заголовками), включая код ответа, и телом содержимого (сообщение).