вторник, 29 июля 2008 г.

RT/CT, Часть 1

RT/CT означает Runtime / Compile time, и речь идет о взаимоотношениях между кодом, структурой программы в коде, настройками, оформленные в коде, и т.д. и данными в базе данных, данными в памяти сервера, настройками в xml и пр.

Это очень интересная и сложная тема, в которую вливаются вопросы ORM и IoC. Основные вопросы — архитектурные (скорость работы, кэши, перекачка в память из памяти), дизайн ("вот как у нас тут всё делается") и затраты ("сейчас это сделаем — потом будем только донастраивать").

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

Самый простой на мой взгляд вопрос RT/CT возникает при разработке любых типов данных, завязанных на справочники: работа с датой и временем, списки стран и городов, флаги, валюты, единицы измерения и т.д. Часть из них уже встроены в операционную систему или используемый фрэймворк, но чаще нет, либо чего-то не хватает. Если разрабатывается крупная система со своей БД, то ответ часто прост: всё будем хранить в БД. Но тоже не всегда.

Возьмем в качестве примера не совсем реальную ситуацию — работа с датой/временем и календарем (т.к. обычно всё уже и так есть). Нужны названия месяцев и дней недели на разных языках, списки праздничных дней, региональные форматы вывода — их можно хранить в базе. А вот схемы расчета когда какой месяц настает (для Израиля и многих мусульманских стран нетривиально) — это чистый код... который настоящие "хардкорные" программисты оформят в виде хранимой процедуры, конечно. "Хардкорные" потому, что всё чаще "серьёзные" задачи автоматизации приходится решать "обычным" программистам облегченными средствами веба, динамических языков, а также java и .NET. Оформить календари в виде кода очень заманчиво: это просто, удобно в отладке и тестировании в духе Calendars.Gregorian.GetMonth(), опять же подсказка в редакторе работает, а благодаря средствам контроля версий такой код находится в большей безопасности. С другой стороны, без дополнительных усилий такие календари и месяцы не будут доступны средствам, опирающимся только на базу — в первую очередь разные генераторы отчетов. Ок, ок — конечно, генераторы сами умеют отображать даты, — я говорил, что пример нереальный.

Поэтому пример второй: единицы измерения, где та же потребность в названиях, форматах отображения и непростые методы расчета значений. Пользуясь нереальным предыдущим примером, можно обрисовать идеал реализации и предугадать возможные ошибки. Дата/время в базе выражаются универсальным независимым от страны или языка числом (миллисекунд с 1 января 1970 года). Соответственно для каждой физической величины (в том числе и времени) нужно было бы ввести универсальное представление числом, а все-все методики пересчета, отображения и конвертации отразить в коде и ресурсах. И перетащить/внедрить всё это в генератор отчетов. И было бы ошибкой переносить какие-то структурные и алгорифмические вещи, подверженные ошибкам, расширению функционала и постоянным улучшениям, в базу данных. Как сказал кто-то умный, ведь данные живут десятилетиями, в то время как код редко "живет" дольше пяти лет (а чаще и года не живет).

Хорошо, но что если нам необходимо в runtime добавить еще одну единицу измерения (завести её в формочке нашей новой учетной системы) и... сохранить?

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

2 комментария:

Анонимный комментирует...

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

Url комментирует...

Это часть 1 :) конкретные предложения будут в части 2. Нужно было время на то, чтобы еще раз подумать и проверить рекомендации в работе.