metaclass: (Default)
[personal profile] metaclass
В процессе срачей с айседом пришел к выводу, что искать идеальные софты/либы/платформы бесполезно, практически все, что хоть как-то используется - достаточно пригодно для использования. Лучше выделить критерии для того, что использовать нежелательно:

С точки зрения пользователя:
1) Отличие от общепринятых UI гайдлайнов. Например, розовый фон, красные кнопки, шрифт Comic Sans и выход из программы по кнопке F1.
2) Неадекватное поведение по отношению к другим программам и ОС. Например, встраивание хуков на системные действия или расширений в Explorer.
3) Издевательства над обычными средствами пользовательской интеграции - например, невозможность без вуду скопировать текст из программы в клипбоард, стандартным сочетанием кнопок или меню.
4) Наличие тупиков в Workflow, т.е. возможность обычными действиями зайти в программе туда, откуда обычными действиями уже не выйдешь (только снимать программу из диспетчера задач, kill и прочая)
5) Отсутствие прогресс-баров и прочей индикации выполнения при длительных операциях, отсутствие возможности их корректно прервать.

С точки зрения админства-деплоймента:
1) Неумение работать в многопользовательской среде/на терминальном сервере.
2) Неумение переживать xcopy-деплоймент и запускаться на чистой машине. В крайнем случае - должно быть документировано, что из окружения требуется (.net, жаба, переменные окружения)
3) Хардкодед пути в бинарниках - убивать нещадно.
4) Размещение своих либ/данных в общих папках, типа system32. Под линуксом - не считается, там за это пакетный менеджер, в идеале, отвечает и там принято всему софту гадить единообразно.

С точки зрения программизма:
0) ad-hoc программирование, без проектирования. Практически сразу заметно по структуре api.
1) Хардкодед значения, не являющиеся математическими константами. Пытать на дыбе авторов. Сюда же - хардкодед пути типа C:/Program Files или C:/openssl/etc (портированный софт
2) Тот же контекст, но в пределах ВСЕЙ ОС, а не только запущенного бинарника (Dragon Naturally Speaking и его апи - сука, ненавижу).
3) Не реентерабельные функции.
4) Отсутствие в АПИ для работы с внешними ресурсами явных пар типа Open/Close, Enter/Exit.
5) Невидимый/недокументированный/мутабельный глобальный контекст. Сюда же - использование такого контекста для работы с внешними ресурсами. Т.е. Open не возвращает "хендл для работы с ресурсом", а просто открывает где-то внутри его и все последующие функции его используют, неявно. Например, коннект к БД - один на всю программу. Или транзакция - одна на весь коннект к БД.
6) Отсутствие для значений getter там где присутствует setter. Забивать гвозди в голову за такое. Т.е. мы можем установить некий параметр, но не можем узнать его значение.
7) Случайное поведение API, не объяснимое переданными параметрами и документированным окружением. Обычно - следствие пункта 5 и общего рукожопия.
8) Использование GUI в явно не-гуишных либах. Последний пример - библиотека для работы с одной железякой, кидающая диалоговое окно при ошибке драйвера. Если ее использовать в фоновом сервисе - капец от входа.
9) Отсутствие в API возможности показать прогресс и прервать длительно выполняющиеся операции.
10) Отсутствие обработки ошибок вообще. УБИВАТЬ! УБИВАТЬ! УБИВАТЬ!
11) Обработка ошибок нормального workflow исключениями. Т.е. "попытка подключится к отсутствующему серверу" кидает исключение, хотя должна быть операция TryConnect
Хуже этого - только парсинг строк в простые значения без функции TryParse
12) Отсутствие логгинга. Сажать на кол, конечно же.
13) Отсутствие исходников - когда вышеописанное вылезет в полной мере, а автор окажется живущим половой жизнью с ежихой в ашраме Гуру Бхактиведанты Свами Прабхувады Ребе Короля Мошиаха - вам придется чинить либу самому.
За вас никто ничего чинить не будет - инфа 100%, еще ни одной либы не видел, где автор бы починил самоочевидную ошибку ранее чем через месяц после баг-репорта.

Т.е., если вы проектируете API - лучше сразу думайте, как его можно однозначно завернуть в красивый класс на c# или сделать обертку для него на хаскеле функциональном языке - резко становится очевидно, что можно делать и чего нельзя.

PS от [livejournal.com profile] denisioru:
- невозможность запустить несколько инстансов софтины одновременно. Да, год 2012й. Лом в жопу.
- изобретение собственных IP-протоколов. Прикладной софт должен работать по UDP или TCP. В редких очевидных случаях - RTMP и иже с ними. Люто, бешено лоботомировать.
- использоать API ОС для ресолвинга имён. За формирование руками DNS запросов и отправку их в неизвестном направлении - насылать нещадный кровавый понос.
- использование нестандартных диалогов открытия и сохранения файлов. Как наказание - выдать блок питания к ноуту юзера, несовместимый с розетками в офисе и дома.
- глюки на мультимониторных конфигурациях. За появление главного окна софтины, напополам распиленное между десктопами - выкалывать глаза.
- создание и использование временных файлов ВНЕ системного каталога TEMP - отправлять сортировать мусорные баки.

PS от [livejournal.com profile] belnetmon:
- невозможность запустить софтину под уровнем пользователя , отличного от админа
- невозможность работы с UNC путями
- гадить во временную папку, которую пидор создал в корне системного диска (NVidia, Intel - привет)
(deleted comment)

Date: 2012-06-04 09:59 am (UTC)
From: [identity profile] serbod.livejournal.com
С фиксацией торговой первички (с проверкой остатков, резервов и взаиморасчетов) 1С 7.7 прекрасно справлялась в 2004 году на изрядно устаревшем (на то время) желдезе, на объемах порядка сотни документов в час, до 50 строк в документе. База строительных товаров, 4 розничные кассы + 2 оператора для оптовиков. Отчеты по продажам, остаткам и взаиморасчетам - без особых проблем. База MSSQL, без терминала. То есть, далеко не оптимальный вариант по производительности.

Сложности при обработке таких объемов (перепроведение, книга продаж). Пробовали разные именитые системы - они даже не смогли данные за месяц загрузить и обработать.

Что касается проверки остатка через ORM в реальном времени - получаем таблицу остатков с фильтром по перечню товаров и складов. Примерно так:

СписокТоваров=Накладная.ДанныеКолонки("Товар");
Фильтр = СоздатьОбъект("Фильтр");
Фильтр.Установить("Товар", СписокТоваров);
Фильтр.Установить("Склад", Накладная.Склад);
Остатки = ТаблицаОстатков.Выбрать(Фильтр);

Можно было по-английски написать, для солидности. Но смысл от этого не изменится. Последняя строка сгенерирует:

SELECT * FROM ТаблицаОстатков WHERE "Товар" IN СписокТоваров AND "Склад" = Накладная.Склад;

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

Про кеширование сальдо с изоляцией - нифига не понял, нужен конкретный пример.
(deleted comment)

Date: 2012-06-04 11:27 am (UTC)
From: [identity profile] serbod.livejournal.com
ТаблицаОстатков - это просто для примера. Физически это может быть view из какой-нибудь огроменной таблицы движений (операций).

В 1С используется комбинация таблицы движений и "кэширующей" таблицы остатков по периодам (обычно по месяцам). Можно запросить остаток за любой момент, сначала выбирается остаток на начало периода, и добавляются движения до конкретного момента. Дешево и сердито. При изменениях задним числом соответствующие последующие остатки пересчитываются. Причем, все это происходит автоматом и не требует ни малейших усилий со стороны программиста. Изменения задним числом в 1С настолько тривиальны, что многие бухи считают это нормой.
(deleted comment)

Date: 2012-06-04 12:24 pm (UTC)
From: [identity profile] serbod.livejournal.com
Как прикладной программист я вас не понимаю. Какие какие еще кеширующие таблицы, что это за цифры, зачем они? Есть объект "ТаблицаОстатков", из которого можно получить остатки других объектов на любой момент. Это же так просто!

Как системный программист я написал класс "ТаблицаОстатков", который производит массу операций по подготовке и выполнению SQL-запроса, извлечению данных. Те самые 2-3 тысячи строк, которые оперируют полями, ключами, идентификаторами и прочей низкоуровневой хренью, в которой даже специалист с двумя высшими образованиями и 5 годами опыта работы будет 2 дня разбираться. Кстати, serialize в таблице остатков нафиг не нужен, мы же свойства объектов храним, а не методы.
(deleted comment)

Date: 2012-06-04 01:15 pm (UTC)
From: [identity profile] serbod.livejournal.com
Меня можно считать кем угодно - не ошибетесь. =) А вот вы дальше опердени под глупого, но богатого буратину не продвинитесь, потому что без разделения разработки на прикладную и системную часть сложность доработок и обслуживания растет в геометрической прогрессии, и кроме пары-тройки стареющих спецов это никто не потянет. В прикладной части вы явно не сильны, не видите разницы между управленческим и бухгалтерским учетом. У ваших клиентов, видимо, директор никогда в программу не заглядывает, ему все данные главбух в папочке приносит.

Date: 2012-06-04 01:34 pm (UTC)
From: [identity profile] serbod.livejournal.com
Остатки - это вторичные данные, которые пересчитываются на основании первичных данных. Хранить их историю крайне глупо, и даже чревато.

Это все равно, что хранить историю колонки "итого", чтобы при удалении какой-то строки вернуть прежнее значение.

Если откатывать не отдельную операцию, а на конкретный момент - то это делается средствами SQL-сервера, по журналу транзакций.
(deleted comment)

Date: 2012-06-04 02:33 pm (UTC)
From: [identity profile] serbod.livejournal.com
Вот живой пример. Склад на фабрике, на складе, например, магниты.

Таблица ОстаткиПоСкладам:
Склад, Товар, Колво, Период
Склад1, Магнит, 10, 01.05.2012 (начало месяца)
Склад1, Магнит, 5, NULL (текущий)

Таблица ДвиженияПоСкладам:
Документ, Склад, Товар, Колво
Приход 11.04.2012, Склад1, Магнит, 10
Расход 15.05.2012, Склад1, Магнит, 5

Допустим, злой бух решил задним числом убрать приход. Проверяем можно ли удалить документ. Для этого выбираем все движения товаров из удаляемого документа, берем остаток на момент до документа, (2 запроса), делаем обход полученных движений с целью расчета остатка на момент движения с проверкой, что он не меньше нуля.

Если все в порядке, то есть варианты:

1. Медленный, но надежный.
Лочим таблицу на запись и повторяем проверку. Потом в транзакции удаляем приход, и записываем новые значения в таблицу остатков. Снимаем лок.

2. Быстрый, ненадежный.
Сначала в транзакции пишем изменения, потом проверяем без лока. Есть очень маленький, но шанс, что кто-то успеет закомиттить свои данные, а наши изменения запорют остаток и его придется пересчитать и переписать.

3. Взвешенный
Используется механизм блокировки не таблицы, а условия. То есть, блокируется запись только определенных значений полей.
(deleted comment)

Date: 2012-06-04 03:12 pm (UTC)
From: [identity profile] serbod.livejournal.com
Конечно, все. Чем глубже насрали задним числом, тем больше объем проверки и больше корректировок остатков по периодам. Причем, в идеале все это производится при блокировке таблицы, поэтому в много-много-многопользовательских системах за такие вещи могут и премии лишить. =)
(deleted comment)

Date: 2012-06-05 08:27 pm (UTC)
From: [identity profile] serbod.livejournal.com
Представьте, что в документе недельной давности вкралась ошибка. Её исправили, причем пересчитанное текущие остатки по-прежнему неотрицательны. Потом приходит клиент и говорит: "Мне выписали 10 штук, а на складе только 8, я на вас... в суд подам". Парадокс? Никакого парадокса. За товаром он пришел сегодня, но продали ему товар вчера. А на состояние "вчера" после корректировки остаток был бы отрицательным. Вот ему и не хватило.

Для таких случаев и существует резервирование. Это еще одна таблица остатков, значения которой учитываются при расчете доступного количества как доступно = остаток - резерв.
(deleted comment)

Date: 2012-06-05 08:50 pm (UTC)
From: [identity profile] serbod.livejournal.com
Удача нипричем, это просто тупо работает.

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

Date: 2012-06-04 12:07 pm (UTC)
From: [identity profile] metaclass.livejournal.com
Я как раз сейчас работаю над темой нормального кэширования расчетов сальдо в произвольных разрезах.

Profile

metaclass: (Default)
metaclass

April 2017

S M T W T F S
      1
2345678
9101112 131415
16171819202122
23242526272829
30      

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Aug. 30th, 2025 09:13 am
Powered by Dreamwidth Studios