Цитата:
Сообщение от
mazzy
Примеры:
- если для записи считают checksum, то поле checksum хранит контрольную сумму (любое значение имеет смысл)
- если для данного клиента включен контроль кредитного лимита, то спросить и хранить этот кредитный лимит
- для данной поставки нужен контроль даты поставки, то спросить и хранить дату доставки. при этом не введенное значение (datenull()) имеет смысл. Например, контроль включен, у клиента спросили, но ему не важно.
- если по договору у клиента надо спросить подтверждение, то хранить Да/Нет, введенное пользователем.
Для checksum хорошее null-значение - 0. Я лично ни за что не стал бы рассматривать 0 как корректное значение рассчитанной контрольной суммы. Для кредитного лимита может быть null-значение 0, как в стандарте. Для дат null-значением может быть maxDate(), раз уж значение dateNull() является допустимым. По поводу UnknownNoYes уже писали

Цитата:
Сообщение от
mazzy
- работать с традиционным null-значением из внешней неаксаптовской базы
- и т.п.
Работа из внешней системы предполагает, как мне кажется, в первую очередь возможность нормально читать/писать такие значения в поля таблиц. Это значит, что те же контейнеры уже не подходят, поскольку нарушают 1-ю нормальную форму и вообще очень неудобны для чтения/записи из внешних систем. Так что остается либо null-значение, либо доп. поле.
Цитата:
Сообщение от
mazzy
другими словами, в алгоритмах используется пара значений - tuple(есть ли значение, значение). Какие манипуляции хотелось бы делать с подобными значениями в Аксапте:
- хранить в базе
- передавать как параметр метода
- спрашивать значения у пользователя на формах и в программных диалогах
- передавать между клиентом и сервером (pack/unpack)
- сериализация = записывать/считывать подобные значения во внешние хранилища (XML, текстовый файл и т.п.)
- что-то еще?
Что-то еще в хотелках/требованиях - чтобы код работы с этими... кортежами не был громоздким

Иначе почему громоздкость фигурирует в оценке каждого варианта?
Цитата:
Сообщение от
mazzy
итак, плюсы/минусы реализаций:
4. временная таблица?
4.1. плюсы
4.1.1. контроль типов
4.1.2. нормально сериализуется
4.1.3. легко работать с набором значений (не одна запись, а несколько во временной таблице)
Стоп-стоп, какие еще несколько записей? Изначально было вот что заявлено:
Цитата:
Сообщение от
mazzy
другими словами, в алгоритмах используется пара значений - tuple(есть ли значение, значение)
А что во временные таблицы можно
вставлять несколько записей - это в данном случае побочный эффект реализации, не более, поэтому такую возможность я бы вообще не рассматривал в рамках данной задачи.
Цитата:
Сообщение от
mazzy
4.2. минусы
4.2.1. неудобно отлаживать
4.2.2. неудобно передавать значения
4.2.3. неудобно создавать подобные пары - слишком много телодвижений надо сделать
3.2.3. очень неудобно отображать эти классы в поля формы или диалога
Непонятно, откуда взялись неудобства

Я бы лично рассматривал
буфер временной таблицы именно как tuple(есть ли значение, значение), реализованный в виде двух табличных полей, вообще на время забыв о том, что во временные таблицы можно
вставлять записи. Что мы получаем тогда с учетом изначальных требований?
- хранить в базе - удобно, как два отдельных поля, чтобы не нарушать 1-ю нормальную форму
- передавать как параметр метода - удобно, как один параметр табличного типа;
- спрашивать значения у пользователя на формах и в программных диалогах - относительно удобно, может потребоваться некий мини-фреймворк для инкапсуляции рутины, связанной с чтением/записью признака наличия значения;
- передавать между клиентом и сервером (pack/unpack) - удобно, пиши себе [buf.HasValue, buf.Value] - и не важно, читаешь ты буфер времянки в pack() или пишешь в unpack(), во всяком случае, так же удобно, как использовать две отдельных переменных, и куда удобнее использования класса для tuple
- сериализация = записывать/считывать подобные значения во внешние хранилища (XML, текстовый файл и т.п.) - удобно, аналогично хранению в базе
Стоит обратить внимание на реализацию метода SysQuery::inRange() - там используется времянка с отдельным полем под каждый базовый значимый тип. Я бы, возможно, использовал схожий подход: сделал бы отдельную
времянку для tuple каждого базового типа и использовал бы соотв. буфер в тех местах, где нужно работать с nullable-значением этого типа. Как уже отмечалось, контроль компилятора - не хуже, чем с обычной переменной базового типа, передача в методы, сериализация - всё есть, отлаживать удобно (развернуть в отладчике, в окне Variables/Watch буфер и посмотреть значения отдельных полей). При всем при этом на времянке можно реализовать вспомогательные методы под часто используемые сценарии, тот же toString() какой-нить - не для отладчика, а для вывода значений в сообщениях. Т.е. получаются плюсы использования класса без минусов возни с инициализацией переменной класса и доступа к его свойствам, особенно в pack/unpack.