Ответ 1
Как введение, это очень упрямо, и я уверен, что у всех разные идеи о том, как он должен работать. Но мои усилия здесь состоят в том, чтобы изложить стратегию с некоторыми хорошими причинами, чтобы вы могли сделать свою собственную оценку.
Пропустить строки или разбор?
Мои личные предпочтения здесь - разобрать все в Контроллере и отправить результаты в Службу. Для этого подхода есть две основные фазы, каждая из которых может отбросить ошибки:
1. Попытка разбора
Когда из пользовательского интерфейса входит пучок string
, я думаю, что имеет смысл попытаться сразу их интерпретировать. Для простых целей, таких как int
и bool
s, эти преобразования тривиальны, а привязки моделей для многих веб-фреймворков обрабатывают их автоматически.
Для более сложных объектов, таких как пользовательские классы, все же имеет смысл обрабатывать его в этом местоположении, чтобы весь синтаксический анализ выполнялся в одном месте. Если вы находитесь в среде, которая обеспечивает привязку модели, большая часть этого разбора, вероятно, выполняется автоматически; если нет - или вы собираете более сложный объект для отправки в службу - вы можете сделать это вручную в контроллере.
Состояние отказаКогда синтаксический анализ не выполняется ("hello"
вводится в поле int
или 7
введено для bool
), довольно легко отправить обратную связь пользователю, прежде чем вам даже понадобится позвонить службе.
2. Подтвердить и зафиксировать
Несмотря на то, что синтаксический анализ удался, все равно необходимо проверить, что запись является законной, а затем зафиксировать ее. Я предпочитаю обрабатывать проверку на уровне обслуживания непосредственно перед совершением. Это оставляет Контроллер ответственным за синтаксический анализ и делает его очень ясным в коде, который выполняется валидацией для каждой части данных, которые совершаются.
При этом мы можем исключить вспомогательную ответственность из уровня сервиса. Нет необходимости, чтобы он разбирал объекты - его единственная цель - фиксировать информацию.
Состояние отказаКогда валидация не удалась (кто-то вводит адрес на Луну или вводит дату рождения 300 лет назад), сообщение об ошибке должно быть сообщено обратно вызывающему абоненту (в этом случае Контроллер). В то время как пользователь, вероятно, не делает различий между сбоем в синтаксическом разборе и отказом для проверки, это важная разница для программного обеспечения.
Переместить объекты Value в UI?
Я бы принимал анализируемые объекты как можно ближе к стеку каждый раз. Если вы можете заставить чью-то другую фреймворк обработать этот бит преобразования, почему бы не сделать это? Кроме того, чем ближе к пользовательскому интерфейсу, чем объекты могут жить, тем легче дать хорошую, быструю обратную связь с пользователем о том, что они делают.
Примечание о связи
В целом, толкание объектов вверх по стеклу приводит к большему сцеплению. Тем не менее, написание программного обеспечения для определенного домена связано с тем, что оно тесно связано с этой областью, независимо от того, что это такое. Если еще несколько компонентов тесно связаны с некоторыми концепциями, которые повсеместно повсеместно распространяются по всему домену - или, по крайней мере, на сенсорные точки API вызываемой службы - я не вижу никакого реального уменьшения архитектурной целостности или гибкости.
Разбор одной большой строки или компонентов?
Как правило, проще всего передать весь string
в метод Parse()
для сортировки. Возьмите пример "80 kg"
:
-
"80 kg"
и"120 lbs"
могут быть действительными весовыми вводами - Если вы проходите в
string
до методаParse()
, он, вероятно, делает довольно тяжелый подъем. Ожидая разбить astring
на основе пространства, не будет властно. - Намного проще вызвать
Weight.create(inputString)
, чем разбитьinputString
на" "
, затем вызватьWeight.create(split[0], split[1])
. - Легче поддерживать функцию ввода с одной строкой
Parse()
. Если возникает какое-то новое требование, то классWeight
должен поддерживать фунты и унции, новый допустимый ввод может быть"120 lbs 6 oz"
. Если вы разделяете вход, теперь вам нужно четыре аргумента. В то время как если он полностью инкапсулирован в логикуParse()
, нет никакой нагрузки для внешних потребителей. Это делает код более расширяемым и гибким.