Два результата для одной операции
От: es3000  
Дата: 08.06.19 11:27
Оценка:
Добрый день!

Делаю программу для обмена с кассой.
С кассой может быть выполнена операция выгрузки или загрузки.

Пользователь программы — это менеджер по работе с товарами.
Менеджер в программе принял новые товары, поменял цены, сделал переоценку.
И теперь нужно, чтобы эта новая информация (новые товары, новые цены) появилась в кассе (в кассовой программе).
Используется Offline-касса.

Менеджер запускает выгрузку информации на кассу.
И в итоге пользователь должен увидеть результат выгрузки.

Для операции я сделал отдельный класс "ТОперацияСКассой", которому передаю параметры, идентификатор кассы и вызываю метод "Выполнить".
Этот класс также имеет свойство "Результат", который должен быть заполнен значением "Успешно" или "Ошибка" по выполнению операции.

Вопрос в следующем.
Кроме непосредственно самого обмена с кассой данный класс должен также выполнить ряд вспомогательных действий:
1) до выполнения обмена:
— запомнить время начала операции
2) непосредственно обмен (выполняется вызовом драйвера кассы)
3) после выполнения обмена:
— запомнить время окончания операции
— рассчитать сводные данные (типа количество выгруженных товаров, общая сумма и т.д.)

Ошибка может возникнуть как до выполнения обмена в пункте (1), во время обмена (при работе драйвера), так и после обмена в пункте (3).

Если ошибка возникает в пункте (2) — то тут ясное дело, что обмен не выполнен и должен быть выдан результат "Ошибка".

А вот если обмен (пункт (2)) выполнен успешно и ошибка возникнет в пункте (3), то тут двоякая ситуация.
С одной стороны обмен выполнен, а с другой стороны — возникла ошибка в каких-то второстепенных действиях.
Какой результат тут установить?

Получается, надо вводить два отдельных свойства-результата?
Типа: "ОсновнойРезультат", "РезультатДоп".
Как-то это выглядит странно.

Подскажите, пожалуйста, как правильнее сделать?
Отредактировано 09.06.2019 11:56 es3000 . Предыдущая версия .
Re: Два результата для одной операции
От: kov_serg Россия  
Дата: 08.06.19 13:00
Оценка:
Здравствуйте, es3000, Вы писали:

E>С кассой может быть выполнена операция выгрузки или загрузки.

Вы определитесть что вы хотите получить. Если вас интересует конечный результат: получилось, не получилось.
Если вы еще хотите диагностировать что именно не получилось и предпринимать дополнительные операции для
выполнения операции обходным путм или отложить на время до восстановления связи с кассой, то результат должен содержать доп сведения
для принятия решения. Но уже другим классом с набором "костылей" для типовых сценариев.

E>Для операции сделал отдельный класс "ТОперацияСКассой", которому передаю параметры, идентификатор кассы и вызываю метод "Выполнить".

E>Этот класс также имеет свойство "Результат", который должен быть заполнен значением "Успешно" или "Ошибка" по выполнению операции.
Класс операции с кассой не должен иметь метода выполнить. Только информацию о том что и как надо выполнить.

E>Вопрос в следующем.

E>Кроме непосредственно самого обмена с кассой данный класс должен также выполнить ряд вспомогательных действий:
E>1) до выполнения обмена:
E>- запомнить время начала операции
E>2) непосредственно обмен (выполняется вызовом драйвера кассы)
Тут могут быть чудеса и временя обработки в десятки секунд и выпадения дров в осадок. (Особенно со всякими доработанными online кассами типа меркурий)
E>3) после выполнения обмена:
E>- запомнить время окончания операции
E>- рассчитать сводные данные (типа количество выгруженных товаров, общая сумма и т.д.)
E>Ошибка может возникнуть как до выполнения обмена в пункте (1), во время обмена (при работе драйвера), так и после обмена в пункте (3).
Пункт 3 который выполняет расчет данных — эмулирует недостающий функционал драйвера кассы?

E>Если ошибка возникает в пункте (2) — то тут ясное дело, что обмен не выполнен и должен быть выдан результат "Ошибка".

Если операция не прошла выдаём ошибку. Кассы все ваши операции особенно фискальные подписывает и сохраняет у себя. Потом можно проверить что в неё записалось.
Ошибок может быть уйма и не только с кассой. Для разгребания полётов пишите логи.

E>А вот если обмен (пункт (2)) выполнен успешно и ошибка возникнет в пункте (3), то тут двоякая ситуация.

Вы что-то усложняете. Но если сильно хочется разделите операцию на стадии (конечный автомат) и анализируйте его состояние или даже путь как он эволюционировал.

E>С одной стороны обмен выполнен, а с другой стороны — возникла ошибка в каких-то второстепенных действиях.

E>Какой результат тут установить?
Результат операции невозможно дальше использовать — ошибка.

E>Подскажите, пожалуйста, как правильнее сделать?

Всё зависит от того что требуется получить. Есть техническое задание в писменной форме?
Re: Два результата для одной операции
От: okon  
Дата: 08.06.19 13:13
Оценка:
E>Подскажите, пожалуйста, как правильнее сделать?

Основная операция это работа электронного кассира — я так понимаю про него речь, который уже съел деньги и обратно их выдать не получится.
Если есть такая возможность технически, то можно все это делать в TransactionScope и любая ошибка будет приводить к Rollback в том числе кассир выплюнет деньги обратно.
Но опять же , даже если есть такая возможность — не факт что это удобный вариант, например клиент внес денег и хочет пойти домой, а то что они чуть позже зачислятся его не особо волнует.

В этом случае после успешной операции кассира — делаете операцию перманентного сохранения результата, вероятность ошибки которой должна быть не большой, например сохранить в локальный файл.

Потом сделать уже операцию по сети, например записать в базу данных, после ее успешного завершения — удалить локальный файл.
Последние два действия нужно обязательно в транзакции делать, чтобы либо все выполнилось, либо ничего и кнопку "Retry".

Сделать возможность "протолкнуть" локальные файлы которые остались не обработанными.
”Жить стало лучше... но противнее. Люди которые ставят точку после слова лучше становятся сторонниками Путина, наши же сторонники делают акцент на слове противнее ( ложь, воровство, лицемерие, вражда )." (с) Борис Немцов
Re: Два результата для одной операции
От: samius Япония http://sams-tricks.blogspot.com
Дата: 09.06.19 01:56
Оценка:
Здравствуйте, es3000, Вы писали:

E>Добрый день!


E>Делаю программу для обмена с кассой.

E>С кассой может быть выполнена операция выгрузки или загрузки.

E>Для операции сделал отдельный класс "ТОперацияСКассой", которому передаю параметры, идентификатор кассы и вызываю метод "Выполнить".

E>Этот класс также имеет свойство "Результат", который должен быть заполнен значением "Успешно" или "Ошибка" по выполнению операции.

E>Вопрос в следующем.

E>Кроме непосредственно самого обмена с кассой данный класс должен также выполнить ряд вспомогательных действий:
E>1) до выполнения обмена:
E>- запомнить время начала операции
E>2) непосредственно обмен (выполняется вызовом драйвера кассы)
E>3) после выполнения обмена:
E>- запомнить время окончания операции
E>- рассчитать сводные данные (типа количество выгруженных товаров, общая сумма и т.д.)

E>Ошибка может возникнуть как до выполнения обмена в пункте (1), во время обмена (при работе драйвера), так и после обмена в пункте (3).


E>Если ошибка возникает в пункте (2) — то тут ясное дело, что обмен не выполнен и должен быть выдан результат "Ошибка".


E>А вот если обмен (пункт (2)) выполнен успешно и ошибка возникнет в пункте (3), то тут двоякая ситуация.

E>С одной стороны обмен выполнен, а с другой стороны — возникла ошибка в каких-то второстепенных действиях.
E>Какой результат тут установить?

E>Получается, надо вводить два отдельных свойства-результата?

E>Типа: "ОсновнойРезультат", "РезультатДоп".
E>Как-то это выглядит странно.
Странно здесь выглядит вот что:
* есть проблема
* есть ее решение, сформулированное в классах и обязанностях ("должен так же выполнить ряд"), с точностью до свойств, которые класс-решение содержит.
* есть понимание того, что решение как бы не вполне подходит
но вопрос заключается именно в том, как натянуть реальность на данное решение...

E>Подскажите, пожалуйста, как правильнее сделать?

Нет такого способа, как определить правильность того или иного решения в вакууме. Одно будет правильнее, т.к. потребует меньше писанины, второе — мозговой деятельности, третье позволит тестировать без подключения к кассе, четвертое — еще что нибудь, а самое правильное приведет к переписыванию драйвера кассы (условно).

Однако, могу предложить рассуждения, от которых можно оттолкнуться при формировании решения.

Итак, то что класс, отвечающий за обмен, должен запоминать время, выполнять обмен, выполнять расчет и еще и предоставлять информацию об ошибках всего — явно перебор для класса, отвечающего за обмен.

Запоминание времени — это контекст любой операции, не только обмена с кассой, но и обмена с жестким диском, принтером, сетевым интерфейсом, вообще с чем угодно. Никаких особых причин совать запоминание времени в операцию обмена с кассой я не вижу. Так и классы, отвечающие за обмен байтами с диском, не содержат никаких данных о времени открытия файла.

Неплохо оглянуться на существующие решения по обмену с чем-либо. На те же файлы. Допустим, нужно прочитать документ из файла. Очень много чего может пойти не так (от неверного пути до БСОД-а). Но программа прикладного уровня всегда может рассчитывать на то, что либо данные файла получены, либо нет (и тогда код ошибки), а если данные файла получены, то документ по ним может быть восстановлен (полностью либо частично), либо нет. И при использовании правильных абстракций, я вообще не вижу особой разницы для прикладного софта между работой с файлом и WebResponse. В результате нетривиального взаимодействия с окружением, к которому прикладной софт не имеет никакого отношения, либо есть код ошибки, либо есть последовательность байт.

В ситуации, когда документ может быть восстановлен частично, неплохо бы на уровне модели документа иметь представление о том, какие его части были восстановлены верно, а какие — отсутствуют, либо восстановлены неверно. Здесь можно оглянуться на работу с мультимедиа в условиях повреждения данных, либо отсутствия части кодеков, когда какие-то из стримов воспроизвести можно, какие-то — нет. Совершенно необязательно запихивать результат в 1-2 поля кода ошибки.

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


Лично меня такие рассуждения приводят к тому, что вместо единого класса ТОперацияСКассой, отвечающего за несколько вещей, следует ввести
1) абстракцию взаимодействия с кассой
2) реализацию абстракции взаимодействия с кассой
3) эмуляцию (Mock) кассы
4) класс (возможно и не один), отвечающий за представление данных непосредственного результата обмена с кассой (без поствычислений). Не знаю специфики, потому не берусь в контексте обсуждения решать, будет ли это похоже на Stream или на JSON документ в памяти.
5) класс (или группа), отвечающий за представление результатов обработки сырых данных обмена с кассой. Более высокоуровневый документ.
6) класс или группа методов, осуществляющая непосредственно обработку результата обмена с кассой.

Будет ли это все "правильнее" чем один класс? При определенных обстоятельствах и под определенным углом зрения. В других обстоятельствах это over-design.
Re[2]: Два результата для одной операции
От: es3000  
Дата: 09.06.19 11:54
Оценка:
O>Основная операция это работа электронного кассира — я так понимаю про него речь ...

Не совсем.

Пользователь — это менеджер по работе с товарами.
Менеджер в своей товаро-учетной программе принял новые товары, поменял цены, сделал переоценку.
И теперь нужно, чтобы эта новая информация (новые товары, новые цены) появилась в кассе (в кассовой программе).
Используется Offline-касса.

Менеджер запускает выгрузку информации на кассу.
И в итоге пользователь должен увидеть результат выгрузки.

Но дело в том, что сама выгрузка может быть выполнена успешно, но возникнуть какая-то ошибка при выполнении дополнительных действий.
Если по операции возвращать только один результат, то в этом случае вернется ошибка и будет не понятно выполнен ли обмен или нет.
Получается, операция выгрузки на кассу должна вернуть два результата: один результат по самой выгрузке и второй результат по дополнительным действиям.

Так?
Re[2]: Два результата для одной операции
От: es3000  
Дата: 09.06.19 11:58
Оценка:
_>Вы определитесть что вы хотите получить. Если вас интересует конечный результат: получилось, не получилось.
_>Если вы еще хотите диагностировать что именно не получилось и предпринимать дополнительные операции для
_>выполнения операции обходным путм ...

Пока требования простые.
Хочу получить следующую информацию о выполненной операции:
1) выполнен ли обмен успешно или с ошибкой
2) успешно ли вычислены сводные данные по операции
И отобразить эту информацию пользователю.

E>>Для операции сделал отдельный класс "ТОперацияСКассой", которому передаю параметры, идентификатор кассы и вызываю метод "Выполнить".

E>>Этот класс также имеет свойство "Результат", который должен быть заполнен значением "Успешно" или "Ошибка" по выполнению операции.
_>Класс операции с кассой не должен иметь метода выполнить. Только информацию о том что и как надо выполнить.

А какой класс будет содержать метод "Выполнить"?
Какой класс фактически будет выполнять обмен?

E>>2) непосредственно обмен (выполняется вызовом драйвера кассы)

_>Тут могут быть чудеса и временя обработки в десятки секунд и выпадения дров в осадок. (Особенно со всякими доработанными online кассами типа меркурий)

Это не страшно.

E>>3) после выполнения обмена:

E>>- запомнить время окончания операции
E>>- рассчитать сводные данные (типа количество выгруженных товаров, общая сумма и т.д.)
_>Пункт 3 который выполняет расчет данных — эмулирует недостающий функционал драйвера кассы?

Нет. Просто рассчитывает какие-то общие итоги.
Например, операция выполнялась 30 сек., выгружено 125 товаров, на общую сумму 234 тыс. руб.

E>>Если ошибка возникает в пункте (2) — то тут ясное дело, что обмен не выполнен и должен быть выдан результат "Ошибка".

_>Ошибок может быть уйма и не только с кассой. Для разгребания полётов пишите логи.

Это понятно. Логи буду писать.
Но сейчас меня интересует только: (а) успех\ошибка самого обмена и (б) успех\ошибка расчета сводных данных.

_>Вы что-то усложняете. Но если сильно хочется разделите операцию на стадии (конечный автомат) и анализируйте его состояние или даже путь как он эволюционировал.


То есть надо хранить результат выполнения каждого перехода от одного состояния к другому состоянию?

_>Результат операции невозможно дальше использовать — ошибка.


Это понятно. А если такая ситуация.
Результат обмена с кассой успешный — кассу можно использовать.
А расчет сводных данных об обмене для отображения пользователю — не успешный — их корректно отобразить нельзя.
В этом случае как?

E>>Подскажите, пожалуйста, как правильнее сделать?

_>Всё зависит от того что требуется получить. Есть техническое задание в писменной форме?
Вот эту тему и можно считать техническим заданием.
Re[3]: Два результата для одной операции
От: okon  
Дата: 09.06.19 12:18
Оценка:
E>Не совсем.

E>Пользователь — это менеджер по работе с товарами.

E>Менеджер в своей товаро-учетной программе принял новые товары, поменял цены, сделал переоценку.
E>И теперь нужно, чтобы эта новая информация (новые товары, новые цены) появилась в кассе (в кассовой программе).
E>Используется Offline-касса.

E>Менеджер запускает выгрузку информации на кассу.

E>И в итоге пользователь должен увидеть результат выгрузки.

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

E>Если по операции возвращать только один результат, то в этом случае вернется ошибка и будет не понятно выполнен ли обмен или нет.
E>Получается, операция выгрузки на кассу должна вернуть два результата: один результат по самой выгрузке и второй результат по дополнительным действиям.

E>Так?

Не совсем понятно есть offline-касса и АРМ менеджера, они на одном компьютере размещаются или нет ? Или как менеджер запускает выгрузку на кассу ?
Возможно и нужно 2 результата выводить, если пользователю эта информация необходима,
если для него это все одна операция , то эту внутренную кухню лучше скрыть и сделать в случае наличия ошибки кнопку повторить действие, если одна из операций не выполнилась и запускать ее.
”Жить стало лучше... но противнее. Люди которые ставят точку после слова лучше становятся сторонниками Путина, наши же сторонники делают акцент на слове противнее ( ложь, воровство, лицемерие, вражда )." (с) Борис Немцов
Re[2]: Два результата для одной операции
От: es3000  
Дата: 09.06.19 12:20
Оценка:
S>* есть проблема
S>* есть ее решение, сформулированное в классах и обязанностях ("должен так же выполнить ряд"), с точностью до свойств, которые класс-решение содержит.
S>* есть понимание того, что решение как бы не вполне подходит
S>но вопрос заключается именно в том, как натянуть реальность на данное решение...

Вопрос заключается в оценке правильности моего решения, в определении не правильных "моментов" решения.
И разработке другого более правильного решения.

S>Нет такого способа, как определить правильность того или иного решения в вакууме. Одно будет правильнее, т.к. потребует меньше писанины, второе — мозговой деятельности, третье позволит тестировать без подключения к кассе, четвертое — еще что нибудь, а самое правильное приведет к переписыванию драйвера кассы (условно).


Да, согласен.
Первые два пункта можно отбросить (готов писать сколько надо, мозговой деятельности не боюсь).
Третий пункт — наверно нужно учесть.
Re[2]: Два результата для одной операции
От: es3000  
Дата: 09.06.19 12:44
Оценка:
S>Однако, могу предложить рассуждения, от которых можно оттолкнуться при формировании решения.

Да, спасибо, рассуждения очень ценные.
Ниже мои уточняющие вопросы.

S>Итак, то что класс, отвечающий за обмен, должен запоминать время, выполнять обмен, выполнять расчет и еще и предоставлять информацию об ошибках всего — явно перебор для класса, отвечающего за обмен.


Согласен.

S>Запоминание времени — это контекст любой операции, не только обмена с кассой, но и обмена с жестким диском, принтером, сетевым интерфейсом, вообще с чем угодно. Никаких особых причин совать запоминание времени в операцию обмена с кассой я не вижу. Так и классы, отвечающие за обмен байтами с диском, не содержат никаких данных о времени открытия файла.


Тогда это должен быть какой-то отдельный класс контекста?

К сожалению, у меня не много опыта.
Я просто не сталкивался с этим и не знаю как это реализуется.

Как обычно реализуются такие классы контекста и как они связаны с классом самой операции?

S>Неплохо оглянуться на существующие решения по обмену с чем-либо. На те же файлы.

S>... программа прикладного уровня всегда может рассчитывать на то, что либо данные файла получены, либо нет (и тогда код ошибки)
S>...
S>Здесь можно оглянуться на работу с мультимедиа в условиях повреждения данных, либо отсутствия части кодеков, когда какие-то из стримов воспроизвести можно, какие-то — нет. Совершенно необязательно запихивать результат в 1-2 поля кода ошибки.

А в каком виде представляется результат работы с мультимедиа?

S>... неплохо бы выделить абстракцию для того, что бы можно было тестировать тот же процесс расчета сводных данных по ранее заготовленным данным, либо по результату эмуляции обмена с кассой даже в условиях отсутствия нужного драйвера.


ОК, сделаю такой класс.

S>Лично меня такие рассуждения приводят к тому, что вместо единого класса ТОперацияСКассой, отвечающего за несколько вещей, следует ввести

S>1) абстракцию взаимодействия с кассой
S>2) реализацию абстракции взаимодействия с кассой
S>3) эмуляцию (Mock) кассы
S>4) класс (возможно и не один), отвечающий за представление данных непосредственного результата обмена с кассой (без поствычислений). Не знаю специфики, потому не берусь в контексте обсуждения решать, будет ли это похоже на Stream или на JSON документ в памяти.
S>5) класс (или группа), отвечающий за представление результатов обработки сырых данных обмена с кассой. Более высокоуровневый документ.
S>6) класс или группа методов, осуществляющая непосредственно обработку результата обмена с кассой.

В целом согласен.
Тогда вот такой вопрос.

Обмен с кассой вызывается из UI-слоя.
Все перечисленные классы надо реализовать в специальном слое, назовем его "Касса"-слой.
Но UI-слою будет не "удобно" оперировать несколькими классами для выполнения операции.
Получается, должен быть еще один класс, который является как бы "агрегатором" для нескольких классов "Касса"-слоя и облегчает взаимодействие UI-слою с этими классами.

Ведь, для пользователя — это одна операция.
Для понимания что произошло, пользователь должен знать прошел ли сам обмен.
И если сам обмен прошел, то пользователь должен увидеть сводные данные обмена.
Если при расчете сводных данных возникла ошибка, то пользователь должен увидеть ошибку расчета сводных данных вместо самих сводных данных.

Так?
Получается, агрегатор все-таки нужен?
Отредактировано 09.06.2019 12:59 es3000 . Предыдущая версия . Еще …
Отредактировано 09.06.2019 12:46 es3000 . Предыдущая версия .
Re[4]: Два результата для одной операции
От: es3000  
Дата: 09.06.19 12:57
Оценка:
O>Не совсем понятно есть offline-касса и АРМ менеджера, они на одном компьютере размещаются или нет ?

Вообще они размещаются на разных компьютерах.
Но это не принципиально.

O>Или как менеджер запускает выгрузку на кассу ?


Менеджер просто в своей программе нажимает кнопку, открывается окно, в окне указывает нужные параметры (склад по которому надо выгружать товары) и нажимает "Выгрузить".
И все.
В ответ должен увидеть результат.

O>Возможно и нужно 2 результата выводить, если пользователю эта информация необходима,

O>если для него это все одна операция , то эту внутренную кухню лучше скрыть и сделать в случае наличия ошибки кнопку повторить действие, если одна из операций не выполнилась и запускать ее.

Да, для пользователя — это одна операция.

Для понимания что произошло, пользователь должен знать прошел ли сам обмен.
И если сам обмен прошел, то пользователь должен увидеть сводные данные обмена.
Если при расчете сводных данных возникла ошибка, то пользователь должен увидеть ошибку расчета сводных данных вместо самих сводных данных.

Кнопка "Повторить операцию" пока не нужна.
Пока достаточно увидеть информацию о результатах обмена.
Re[3]: Два результата для одной операции
От: samius Япония http://sams-tricks.blogspot.com
Дата: 09.06.19 19:13
Оценка:
Здравствуйте, es3000, Вы писали:

S>>Запоминание времени — это контекст любой операции, не только обмена с кассой, но и обмена с жестким диском, принтером, сетевым интерфейсом, вообще с чем угодно. Никаких особых причин совать запоминание времени в операцию обмена с кассой я не вижу. Так и классы, отвечающие за обмен байтами с диском, не содержат никаких данных о времени открытия файла.


E>Тогда это должен быть какой-то отдельный класс контекста?

Я о том, что когда нужно что-то замерить, то обычно замеряет тот, кому нужно, вызывающий код. А не тот код, который отвечает за реализацию конкретной операции. Иначе придется в любой код совать обязанность запоминать время начала его выполнения и время конца, просто на тот случай, если кому-то потребуется. Вызываемому коду тоже может понадобиться, но только в случае, когда в зависимости от времени выполнения операции ему придется менять логику работы, т.е. когда это непосредственно необходимо и не может быть отчуждено вовне.

E>К сожалению, у меня не много опыта.

E>Я просто не сталкивался с этим и не знаю как это реализуется.

E>Как обычно реализуются такие классы контекста и как они связаны с классом самой операции?

Обычно в саму операцию/кусок кода тащится лишь тот минимум, который необходим для выполнения самой операции. Если, например, нам потребовалось написать в журнал время начала и конца операции, то обычно с этим может справиться вызывающий код. Но если в журнале нужны какие-то промежуточные результаты вычислений, придется знание о журнале в какой-то форме внести в саму операцию. Передать журнал явно, или организовать подписку на смену стадии выполнения, может быть создать в операции виртуальный метод, который будет перекрыт наследником....

S>>Здесь можно оглянуться на работу с мультимедиа в условиях повреждения данных, либо отсутствия части кодеков, когда какие-то из стримов воспроизвести можно, какие-то — нет. Совершенно необязательно запихивать результат в 1-2 поля кода ошибки.


E>А в каком виде представляется результат работы с мультимедиа?

Это зависит от задачи. Для задачи "показать" или "сконвертировать" результат будет один, для задачи "распознать лица" — другой.

E>Обмен с кассой вызывается из UI-слоя.

Обобщу. Инициируется в том числе с UI. В общем случае это может быть регулярная запланированная операция.
E>Все перечисленные классы надо реализовать в специальном слое, назовем его "Касса"-слой.
E>Но UI-слою будет не "удобно" оперировать несколькими классами для выполнения операции.
E>Получается, должен быть еще один класс, который является как бы "агрегатором" для нескольких классов "Касса"-слоя и облегчает взаимодействие UI-слою с этими классами.
Есть такой шаблон проектирования. Фасад.

E>Ведь, для пользователя — это одна операция.

E>Для понимания что произошло, пользователь должен знать прошел ли сам обмен.
E>И если сам обмен прошел, то пользователь должен увидеть сводные данные обмена.
E>Если при расчете сводных данных возникла ошибка, то пользователь должен увидеть ошибку расчета сводных данных вместо самих сводных данных.
Конечно, результат операции нужен. Но пользователь — это ненасытная тварь, которому подавай еще как минимум анимированные бегущие точечки в лучшем случае, а в худшем — выводить на экран стадии процесса обмена, что бы пользователь мог набрать поддержку и сообщить ей, в какой стадии завис обмен.

E>Так?

E>Получается, агрегатор все-таки нужен?
Фасад. Если он кому и нужен — так это программисту. Как компьютеру пофигу, как написана программа, т.к. он выполняет двоичный код, так и пользователю пофигу, т.к. он видит лишь морду. Наличие анимированных точек в операциях, занимающих больше секунды, пользователю важно. А есть ли там фасад внутри, насколько удобно из UI вызывать операции обмена с кассой — кашлять.

Мотивация к внутренней организации кода — она лежит вне функциональных требований к ПО.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.