Pull to refresh

Comments 6

Первое бизнес-правило на такой случай: состояние HomeAddress клиента (Customer) должно быть таким же, как состояние BillingAddress у Order (заказ).

Не состояние, а штат (единица административного деления).

Customer customer = SomeDataSource.GetCustomer(order.CustomerId);
Address shippingAddress = SomeDataSource.GetAddress(order.ShippingAddressId);


А вот и источник будущих проблем: «библиотека» бизнес-правил зачем-то запрашивает данные напрямую неизвестно откуда, вместо того, чтобы работать по переданному состоянию (либо явно озвучить свои требования во входных параметрах).

Как понятно из вышеуказанного комментария, мы предполагаем, что свойство HomeAddress правильно загрузилось из источника данных. Хотя в 99,99% случаев, вероятно, так и будет, по-настоящему надежный API должен учитывать и такой сценарий, когда этого не произойдет. [...] В данном случае важно, что мы ничего не знаем о вводе, который можем получить, либо о данных, извлекаемых из кода, которые мы не контролируем.

Если мы вызываем какой-то внешний код, то у него есть контракт. Этот контракт явно говорит, будет загружено то или иное свойство, или нет. Если контракт не выполнен, то надо (а) бросать эксепшн и (б) бить по голове автора кода. Это, кстати, отличие вызываемого нами кода при

Другое дело, если внезапно HomeAddress может быть не заполнен (по бизнес-правилам). Вот тогда его надо оборачивать в проверку, и уточнять ее результат у автора требований.

Боб: Разве твой код не должен обеспечивать эффективную обработку нескольких заказов одновременно?
Вы: Ах… да, конечно.

Нет. Нет, серьезно, не должен. Это новое требование, которое предполагает другой сценарий использования, а измененный сценарий использования предполагает вдумчивое переписывание кода.

Вы не согласны? А задумайтесь о простой вещи: как должна себя вести пакетная загрузка заказов из ACME, когда два заказа из пакета в 100 штук невалидны. Отменить все? А почему?

Эту проблему легко решить, если принимать массив заказов, а не один, плюс добавить какое-нибудь простое кэширование.

Уж если принимать массив заказов, то и забирать данные из источника данных надо массивом, а не в цикле. Простое кэширование — это совершенно наивная оптимизация, которая может будет работать, а может — нет. Ах, источник данных не умеет? А почему он не умеет, а мы должны уметь?

Но на самом деле, если вспомнить замечание о том, что не надо запрашивать данные, а надо получать их, то мы бы изначально избежали проблемы, просто потому, что у Боба уже есть доступ ко всем данным, которые он загружает.

Давайте скорректируем наш пример, чтобы «ничто» в нем тоже обрабатывалось.

А зачем? Если мы корректно обработали сценарии выше, то это произойдет само собой. Какое нам дело до того, валиден ли заказ (особенно учитывая, что часть валидности заказа — это мы же, так что здравствуй, рекурсия), когда мы проверяем в нем конкретное правило? Нас интересует, чтобы то, от чего зависит это правило, было корректно.
Это, кстати, отличие вызываемого нами кода при

Упс, сорри. Отличие вызываемого нами кода от принимаемых нами данных: на первое есть контракт, который от нас не зависит (разве что у нас есть средства убеждения), а второе — это наш контракт (и средства убеждения применяются к нам). Что любопытно, в среднем, степень недоверия (количества проверок) к принимаемым данным традиционно выше, чем к возврату вызываемого кода.
Интересный, кстати, первый кусок кода. В первом случае мы грузим кастомера и у него берем адрес, а во втором случае у заказа грузим адрес. А че у кастомера-то адрес не загрузили тогда, если у заказа грузится. Надо уж последовательным быть. Если заказ у нас с адрсом, то и кастомер должен быть с адресом. Если у заказа мы адрес явно загружаем, то тогда и у кастомера адрес надо явно загружать. Какой-то пример корявый.
В некоторых стандартах существует целых 15-ть типов «ничто». :)
Хм… В целом вся статья укладывается в одно давно известное выражение: «Более 70% кода системного программиста — это проверка на ошибки и обработка нештатных ситуаций.»
Написание библиотек, в общем-то, тоже системное программирование.
P.S. Кстати, о дизайне API здесь ни слова )
Статья из серии «вредные советы для программистов». Маскируйте ошибки в клиентском коде, игнорируйте неправильный ввод, логируйте исключения и забывайте про них. Пусть потом бухгалтерия в конце года голову ломает, почему у них остатки не сойдутся. Зато библиотека работает быстро и шеф доволен. Поколотник вровень выступает, чо.
Sign up to leave a comment.