SDK, работа над ошибками
Давайте поможем инженерам из Amazon с их SDK 2.0. Разберем наиболее серьезную ошибку – частичную инициализацию объекта.
В прошлой заметке я упоминал, как создаются объекты в SDK. Если коротко, у классов скрыты конструкторы, и нужно пользоваться билдером. Получается что-то вроде такого:
GetObjectRequest request = GetObjectRequest.builder()
.bucket("acme-releases")
.key("path/to/file.txt")
.ifEtagMatches("....")
.ifModifiedSince("...")
.build()
Билдер не знает, какие из параметров обязательны, а какие нет. В примере выше код работает. Если убрать вызов .bucket или .key, все скомпилируется, но при запуске получим:
Execution error (IllegalArgumentException)
at ....xml.internal.marshall.SimpleTypePathMarshaller
Parameter 'Bucket' must not be null
Обратите внимание, что ошибка приехала из какого-то XML-маршаллера, хотя никакого XML и тем более маршаллизации здесь нет. Тело пустое, и просто составляется URL.
Подчеркну: программистам из Амазона вполне ОК, что объект инициирован
частично. Спрашивается, что можно сделать с объектом GetObjectRequest
, если у
него не заполнен бакет? Ничего. Зачем тогда позволять такую ситуацию?
Как они вообще представляют работу со своим SDK? Пользователь садится и перебором проверяет, какие поля нужны, а какие нет? Ладно я знаю, что бакет и ключ необходимы, но ведь кто-то не знает. И узнает он только когда бахнет прод.
Проблема решается просто. Все поля объекта делятся на обязательные и нет – по
аналогии с аргументами args
и kwargs
в Питоне. Обязательные поля потому так
и называются, что без них невозможно дернуть конструктор или порождающий
статичный метод. В нашем случае обязательны бакет и ключ. С ними код становится
таким:
GetObjectRequest request = new GetObjectRequest(
"acme-releases", "path/to/file"
).withEtag("...")
.withModifiedSince("...")
либо то же самое с билдером:
GetObjectRequest request = GetObjectRequest.builder(
"acme-releases", "path/to/file")
.etag("...")
.modifiedSince("...")
.build()
То есть хоть разбейся в лепешку, но обязательные параметры передай.
Ну? Что мешало так сделать? Здесь даже паттерны сохранены, чтобы не пострадало чувство прекрасного.
Заметим, что я не говорю отсебятину: все это сказано в книге Effective Java авторства Джошуа Блоха. Он так и пишет: используйте неизменяемые объекты, не допускайте частичной инициализации, требуйте обязательные поля сразу – не надейтесь, что кто-то заполнит из позже. Кумир джавистов говорит, как делать правильно. Почему в Амазоне решили, что сами с усами?
Впрочем, пока я писал это, подумал – может, все гораздо проще? Может быть, за SDK сажают мидлов и стажеров, пока они без задач? Скажем, наняли стажера, а у тимлида релиз, погружать человека некогда, поэтому его сажают за SDK. Вполне похоже на правду.
У нас так было в Датаарте: пока человек без работы, его сажали за всякий внутренний хлам. Форму заказа пиццы, аукцион парковочных мест, каталог сотрудников. Все это было крайне низкого качества, потому что шло через десятки джунов и мидлов без какого-либо контроля качества.
Может и в Амазоне такой же порядок? Кто знает, расскажите. Потому что чем иначе объяснить такое качество SDK – я не знаю.
Нашли ошибку? Выделите мышкой и нажмите Ctrl/⌘+Enter