- PVSM.RU - https://www.pvsm.ru -
Дабы не топтаться в парадном, покуривая мануалы, пытаясь вчитаться в рекламные буклеты или вслушаться в страстные заверения очередного волнистого попугайчика от АйТи, приглашаю Вас войти в мир Cache' с задворков — совершить этакое нелегальное погружение. Как человек, работающий с этой технологией не первый (а второй!) десяток лет и мало-мало знакомый с ней, надеюсь что смогу осилить роль гида в этом простеньком путешествии.
Интересующимся предметом разговора вкратце доложу: речь пойдет о СУБД с одной стороны достаточно неочевидной, с другой — претендующей на роль серебряной пули для разработчика всевозможных ИС, КИС, ИАрПи и проч. и проч. Если вы имеете хоть какое-то отношение к рынку программного обеспечения, потраченное время окупится — я попытался уместить сюда мой лучший опыт последних лет. Отнюдь не академический. И даже если Вы уже пытались постичь Cache' неудачно — поверьте, иногда зайти даже в самое респектабельное заведение из подворотни (с нужным провожатым) оказывается более результативно. И чего уж греха таить и скромничать — часто дело именно в спутнике.
Будете смеяться, но самое сложное в этом процессе — установить и настроить веб-сервер. В т.ч. и потому, что коллеги из Intersystems не очень-то казисто отработали.
Я в качестве такового уже много лет полагаюсь на Apache. При тысячах пользователей вполне приемлемый вариант. Соцсети и прочие нагрузочные развлечения с их nginx'ами выходят за рамки обсуждения. Cache' в первую очередь СУБД, а потом — все остальное. Но! Захотите отмасштабировать — легко. Если Вы прямо сейчас позвоните по номеру 8-800-2600-… то я сделаю для вас не только масштабирование, но и индивидуальный амулет-оберёг от багов и дэдлоков, настроенный исключительно на Вашу ауру.
Но к делу. На http://www.apache.org/dist/httpd/binaries/win32/ [1] забираем файл httpd-2.2.22-win32-x86-no_ssl.msi [2]. Здесь версия 22, но если Вам достанется более поздняя, не страшно, главное чтобы 2.2. Если у Вас уже есть веб-сервер Apache, этот шаг опускаем — Cache' минимально затрагивает настройки — об этом после следующей картинки. Любителям IIS могу предложить лишь самостоятельно развлекаться с настройками — я на этих страницах предлагаю простой путь, а IIS вечно отирается в парадных.
Девять кликов, дважды введенное "localhost", немного перьев и… самое сложное позади.
Следующий шаг в два раза проще. Но нам понадобится зарегистрироваться: http://download.intersystems.com/download/ [3]. Придется заполнить аж 11 полей и нажать шесть галок (нет хуже маркетологов, чем у лучших производителей СУБД), но искусство требует жертв:
Успели за 5 минут? Я тоже!
Хотелось бы тут сказать "вуаля" и повтыкать восклицательных знаков, ан нет — ребята из Интерсистемз (далее я буду ласково говорить "ИС") снисходительно позволили и нам продемонстрировать, насколько хорошо мы владеем напильником.
Находим файл C:Program Files (x86)Apache Software FoundationApache2.2confhttpd.conf
В самом его низу (помните, мы из подворотни пришли) находим страшную конструкцию вида
#### BEGIN-CSP-SECTION() ####
LoadModule csp_module_sa "C:/Program Files (x86)/Apache Software Foundation/Apache2.2/CSPGateway/CSPa22.dll"
Alias /csp/ "C:/InterSystems/TryCache/CSP/"<Directory "C:/InterSystems/TryCache/CSP">
AddType application/x-csp .csp .cls .zen .cxw
AllowOverride None
Order allow,deny
Allow from all
</Directory>
#### END-CSP-SECTION() ####
#### BEGIN-CSP-SECTION(TRYCACHE) ####
Alias /trycache/csp/ "C:/InterSystems/TryCache/CSP/"
#### END-CSP-SECTION(TRYCACHE) ####
Оставляем от нее лишь
#### BEGIN-CSP-SECTION() ####
LoadModule csp_module_sa "C:/Program Files (x86)/Apache Software Foundation/Apache2.2/CSPGateway/CSPa22.dll"
#### END-CSP-SECTION() ####
Немного ее приукрасив, получим:
#### BEGIN-CSP-SECTION() ####
LoadModule csp_module_sa "C:/Program Files (x86)/Apache Software Foundation/Apache2.2/CSPGateway/CSPa22.dll"
<Location /csp>
CSP On
SetHandler csp-handler-sa
</Location>
#### END-CSP-SECTION() ####
Счастье — в простоте. Я, строго говоря, уже и не помню, в чем отличие. Но то, что вы видите в итоге — работает. И еще как работает. А то, что записывается по-умолчанию — глючит так или иначе.
Как остановить и перезапустить Apache, надеюсь разберётесь. Подсказка: ищем в трее красное пёрышко с зелёной стрелкой — оно реагирует на мышь, поверьте.
Вы себе не представляете, как приятно приветствовать Вас в Cache' через пять минут общения. Ну а если чуть позже, то за плохие "эти ваши интернеты" я не отвечаю.
Проверяем, что все работает: http://localhost/csp/samples/ZENDemo.Home.cls [4] — наблюдаем гипно-треугольник? Значит, все ок. Браузер может попросить отображать SVG-содержимое — я разрешил и вам советую.
Уже увидели кубик в трее? Если нет, показываю (ищем справа внизу экрана):
Вот от этого самого кубика и будет происходить все дальнейшее. Но только если он синий. А вот если кубик серый — значит Cache' у вас не запустилось — вэлкам ту каментс.
Самое время простить разработчиков за скверную конфигурацию Apache и настроиться на позитивный лад. Тем более, что в ближайшее время они, разрабы ИС, нас более чем не подведут.
Например, на кубик Cache' как ни дави — правой ли кнопкою, левою ли — меню всегда одинаковое:
Вначале подглянем в портал управления системой. Я знаю пару компаний, в которых никто не умеет им пользоваться вовсе и при этом заведения процветают. Нам же от портала нынче требуется, чтобы он создал область для работы.
Различаем базу данных и область:
База данных Cache' (Database) — это файл на диске, записи в котором принадлежат нашей БД на том простом основании, что они находятся в этом файле.
Область (Namespace) — это определение в конфигурации Cache', в котором собрана информация о том, какими БД и для каких целей мы пользуемся. Область может брать программы из одной БД, а данные — из другой. Это одна из основ масштабирования в Cache' — просто и очень удобно. Изменив определение области я могу мгновенно переключить всех пользователей системы на работу с обновленными программами, но с текущими данными — что я и делаю раз примерно в две недели — подменяю версии всех программ, а пользователи этого практически не замечают.
Создаем область:
Здесь, кстати, как раз заметно, что для области глобалы (разучите это слово — так в Cache' называются хранимые данные) и программы могут браться из различных баз данных.
Поскольку мы хотим для новой области создать новую БД, вначале делаем это:
Далее "Далее", еще раз "Далее" и "Завершить" — БД создана, а мы вернулись к созданию области:
И вот:
Завершена следующая пятиминутка общения с Cache'. У нас теперь собственное приватизированное поле для экспериментов. Результатов все еще нет, но через пару-тройку минут мы с Вами воздвигнем что-нибудь — гарантирую.
У Вас тоже руки чешутся что-нибудь выдать на-гора? Солидарен. Давим на синий кубик справа внизу:
Студия спросит нас о том, с какой областью мы будем работать — выбираем BS и жмем OK, пароль нам пока не пригодится:
Изначально Студия Cache' предстает перед нами в виде довольно сложной конструкции:
Но немного поработав с крестиками и перетаскиванием, можно добиться адекватного представления. "Инспектор", "Просмотр" и проч. нам понадобятся, но позже, а на следующей картинке подсвечиваю, как их включить (четыре кнопки вверху), в случае-чего. Мне удобно так:
В этом месте борьба между желанием продемонстрировать очередной "Hello world!" и соответствовать реальности программирования была выиграна последней — играем по-взрослому.
Воображение, как мне кажется, превосходно помогает проектировать ПО. Но при постановке задачи нет худшего советчика — и очень важно об этом не забывать. Поэтому поступим просто. Воспользуемся одной из моделей Library of Free Data Models from DatabaseAnswers.org. [5] Таким образом, опустим как этап постановки задачи, так и проектирования. В любом случае Cache' здесь не помощник.
Модель возьмем, к примеру такую [6].
Реализовывать предлагаю слева-направо и сверху-вниз. Ну или примерно так.
Классы — это наше всё. О разделах Студии "Программы", "CSP-файлы" и о "Другое" забудьте. Это для ребят, заинтересованных фасадом. И для уважаемых
пенсионеровветеранов Cache'.
Итак, создаем класс легким движением правой кнопки:
Следует заметить, что классы в Cache' располагаются в пакетах. Например, так:
С изобретением названий пакетов и их вложенности рекомендую быть очень осторожными. Бритва Оккама [7], как ее мне когда-то преподнесли, говорит о том, что не стоит приумножать число сущностей сверх необходимого. Однако немногие с этим справляются. Ведь труднее всего понять банальную идею — ее можно знать, уметь воспроизводить её различными органами, учить ей других, уметь использовать. Но не понимать при этом. Принципы Ле Шателье [8], Гейзенберга [9], Оккама и Бутерброда [10] многие люди не смогут понять никогда. Ведь они уверены, что УЖЕ их понимают.
Итак, после запроса создания класса нам покажут соответствующий диалог:
Как же называть пакеты и классы?
Тут впору вспомнить о шаблонах проектирования [11]. Когда претендент на собеседовании на вопрос "Какие шаблоны чаще используете?" отвечает: "Разные — вот, конвейер [12] хорошо идет...", — сразу понимаешь, что перед тобой человек ответственный и готовый к рутине. И не готовый давать названия пакетам в Cache'.
Cache'-проектировщик должен всегда мыслить объектами предметной области [13] (Domain Model, DM). Ночь. Улица. Фонарь. Аптека. Кому неймется использовать абстракции — просьба входить с парадного. У нас здесь всё по-простому — всяческие "регистры учета" мы традиционно доводим до жидкого состояния и сливаем в. В качестве компенсации за мучения типа "ну как же это обозвать, чтобы было в DM?" рано или поздно наступает совершенная синергия — система начинает отвечать адекватно на воздействия, к которым проектировщик ее не готовил.
Признак того, что Вы знаете этот шаблон простой: На половину новых запросов заказчика Вам ничего не нужно делать. Система ведет себя точно так же, как и реальный бизнес — процветает.
DM — это главный шаблон. И он же пригодится нам первым.
Еще одна небольшая ремарка:
Cache' предлагает не просто хорошую реализацию модели предметной области. Здесь очень лаконичными и удобными средствами обеспечивается инкапсуляция не только данных, но и поведения объектов предметной области в соответствующие классы.
Итак, обзываем:
И сразу же давим "Завершить". Дело в том, что после нажатия "Далее" Вам покажут совершенно бесполезную дополнительную форму, так что не хочу тратить наше время.
Вот именно так выглядит болванка класса в Cache':
Не знаю, как у вас, а у меня сердце замирает, когда я вижу подобные конструкции. Ничего лишнего. Нет этих дурацких "public static void main" и прочих include stdio.h — свобода!
При всей видимой простоте — тысячи строк системного кода, любезно предоставленного ИС, уже сейчас (после компиляции, разумеется) позволят работать с этим классом. Мы еще ничего не делали, но система уже умеет создавать его экземпляры, удалять их, выполнять запросы и многое, многое другое. Только потому, что он унаследован от системного класса %Persistent, который реализует хранение объектов и доступ к ним.
Но без данных это делать не очень разумно. Наполним наш класс свойствами (прямо внутри окошка используем правую кнопку мыши):
Также предлагаю сразу жать "Завершить". Кнопку "Далее" мы используем, но чуть позже.
Сверяемся со схемой. Осталось еще два свойства сущности "Место представления"- добавляются они точно так же по правой кнопке. Или с помощью "Ctrl-C + Ctrl-V". Затем предлагаю сразу скомпилировать класс:
Теперь проверим, что этот класс работает.
Вначале пощупаем его как объект. Для простоты сделаем это через терминал Cache'. Жмем на кубик в трее, выбираем "Терминал":
Получаем терминальное окошко с командной строкой Cache'. "USER" это область по-умолчанию. Можете порыться в настройках, чтобы изменить ее на "BS".
Но есть способ проще — команда смены области "zn". После перехода в нашу область создаем экземпляр класса, заполняем его свойства и сохраняем:
Узел: papahost, Экземпляр: TRYCACHE
USER>zn "BS"
BS>set obj = ##class(place.One).%New() // Не заботимся о конструкторе
BS>set obj.Name = "Шапито" // Не заботимся о сеттерах-геттерах
BS>set obj.Description = "На площадке у вокзала"
BS>do obj.%Save() // Не заботимся о том, как происходит сохранение данных
Не пугайтесь. Это только для проверки. В реальной разработке объекты появляются и сохраняются более цивилизованно. Об этом немного ниже.
Все наши объекты представлены также и как SQL-таблицы. Вообще-то доступов к данным несколько — можно работать с ними как с объектами (выше мы это попробовали), как с таблицами (об этом чуть ниже), и получать к ним т.н. "прямой доступ". О последнем я здесь вообще умолчу — не зная о нем вы мало потеряете, а захотите разобраться, думаю осилите.
Для SQL-доступа к данным на нашем кубике нужно выбрать "Портал управления системой", и перейти к SQL-запросам:
Далее:
1. Выбираемаем нашу область"BS"
2. Вводим запрос "select * from place.One"
3. Исполняем запрос
4. Видим строчку таблицы, куда отобразился сохраненный нами объект.
SQL-доступ позволяет в полной мере использовать обычный SQL-синтаксис. Можете поэкспериментировать, однако есть один совет: я не использую команды INSERT, UPDATE и DELETE на классах предметной области. Обработка триггеров и событий (например при сохранении) может отличаться. И весь труд вложенный в реализацию предметной области пойдет прахом при использовании этих команд. Вместо команд SQL мы будем использовать методы %New(), %Save(), %DeleteId().
Итак, надеюсь, что у Вас тоже все получилось. То есть мы создали класс с простыми свойствами и убедились в его работоспособности.
Я точно не помню, в какой версии Cache' появился ZEN, но точно знаю, что для меня с этого момента сверхтонкий клиент стал окончательно единственным и безальтернативным клиентом для Cache'. Скажу больше — если во времена CSP (Cache Server Pages — технология из серии asp, jsp и т.п.) переход от задачи на CSP+Cache к задаче на PHP+MySQL и обратно происходил спокойно и ровно, то с ZEN'ом это уже не так — трудозатраты при использовании ZEN (и БД, реализующей предметную область) настолько смехотворны, что любой иной способ проектирования, разработки и сопровождения воспринимается как каторжные работы. В общем, как в том бородатом анекдоте — не используя ZEN в Cache' на новых задачах Вы поступаете либо глупо, либо подло по отношению к заказчику.
И я писал это дольше времени, чем сейчас потрачу на демонстрацию. Жмем "Создать":
Переходим в закладку "Zen" и выбираем "Новая Zen-страница":
Далее нам предлагается форма для ввода. Скажу честно — работая с ZEN уже более 5 лет, я вижу ее наверное, в третий раз. В основном для создания страниц я копирую код наиболее подходящей страницы ZEN, уже созданной когда-то и вношу нужные изменения. Но для первой страницы воспользуемся ею:
Вы уже поняли, что zen-страницы — это те же классы. И они так же упакованы в пакеты. Придумаем название:
И сразу же жмем "Завершить". "Далее" прошу не трогать — Вы попадете в место, в котором испытываешь некоторую неловкость за поставщика продукта. Должно получиться так:
Ого навалило! Когда я говорил о том, что не пользуюсь шаблоном, я имел в виду именно подобные эффекты. Приводим в порядок и компилируем (Ctrl-F7):
В принципе, мы приложение создали. Не видите "Hello, world!"? Я тоже. Но приложение готово к работе. Перейти к нему можно нажав глобус в меню (правее кнопки компиляции) или "F5". Но есть два нюанса:
1. Адрес для просмотра будет выглядеть как http://localhost:57772/csp/bs/zui.Places.cls [14] — дело в том, что при установке Cache' развертывает на 57772 порту веб-сервер для своих нужд и почему-то пытается через него же демонстрировать наши успехи в Студии. Этот веб-сервер имеет ряд ограничений и использовать его нам нежелательно. Поэтому настроим отображение страниц из Студии в нашем Apache — для этого в меню Студии выберем "Проект" — "Настройки", а во вкладке "Дополнительно" появившегося окна зачистим порт (уберем все, начиная с двоеточия, чтобы вышло localhost [15]):
После чего в меню Студии сохраним проект — "Файл" — "Сохранить проект".
2. Дело в том, что когда мы создавали область, для нее система создала csp-приложение (ZEN работает поверх csp). Доступ к вновь созданному приложению ограничен — нам предложат ввести имя и пароль. И это хорошо! Но на создание пользователя и назначение ему прав придется потратить немного времени. Ждем на кубик и открываем "Портал управления системой"
(и когда-же наконец ИС уберет раздел DeepSee… или уволит этого маркетолога — назло не куплю!)
Кнопка "Создать Нового Пользователя" довольно заметна — и особенно режет глаз человеку, немного знакомому с Русским Языком. Интересно, переводчик сего тоже сдавал по нему ЕГЭ? Не похоже, что как мы — по-старинке. О безопасности, случись что займетесь Cache', рекомендую озаботиться — как минимум вникнуть в "Стандарт настроек безопасности СУБД Intersystems Cache'" [16] — иногда месяц работы одного технического писателя полезнее года мытарства команды разработчиков — текст критически полезный. Если найдете, где в Портале находится аудит безопасности — тоже обязательно исследуйте — расширяет кругозор.
Для целей же знакомства поступим просто — создадим пользователя с правами %All — то есть "All Inclusive" — разрешено все — ИС умеет дать вам почувствовать себя богом (иногда):
Вводим имя и два раза пароль — больше ничего руками не трогаем. Пока. Жмем "Сохранить" и переходим в закладку "Роли". Выбираем роль %All, и назначаем ее пользователю:
Должно получиться так:
Вообще-то, Cache' (и ZEN) отлично реализует подход "пользователь-роль-ресурс". Но боюсь, моего времени на это может не хватить — экспериментируйте сами. Получите массу позитивных эмоций. Надеюсь. Но вернемся в Студию и нажмем "F5" (или глобус). Введем имя и пароль на zen-странице, открывается наше первое приложение:
И опять же — ничего лишнего. Красота! Трудно представить, что эту восхитительно чистую страницу мог испортить своим присутствием какой-то "Hello, world!" (иностранный агент).
Опытный разработчик поймет, чему я на самом деле радуюсь — конечно же отсутствию ошибок. Она вертится! 90% работы сделано.
Эта часть должна получиться немного короче предыдущей. Что закономерно — создать шедевр в виде чистой страницы гораздо сложнее, чем подготовить форму для ввода и отображения мест цирковых представлений.
Помните, что один объект класса "Место представления" мы уже сохранили в БД? Займемся его отображением. Для этого нам понадобится компонент ZEN с именем "tablePane":
Здесь и далее буду размещать исходники, которые можно загрузить в Студию из меню "Инструменты" — "Импортировать локально".
Исходник: places1.xml [17]
Скомпилируем и посмотрим, что получилось:
С лэйаутом проблемы, но это дело поправимое. Главное, что мы научились отображать данные. Теперь займемся их записью с пользовательского интерфейса. О реализации шаблона MVC [18] (model — view — controller) в документации по ZEN написано много, но я не читал и Вам не советую — лучше покажу, как это работает.
Для начала, нужно наш хранимый класс унаследовать от %ZEN.DataModel.Adaptor:
Исходник: one1.xml [19]
А в классе интерфейса добавить:
1. Контроллер
2. Форму с указанием, что ее данными занимается наш контроллер
3. Методы обработки событий (здесь метод сохраняет данные и обновляет таблицу)
Исходник: places2.xml [20]
В браузере:
Добавим запись:
Надеюсь, у вас тоже получилось?
Для того, чтобы при выборе строки таблицы в контроллер подгружались данные объекта, нам тоже понадобится немного кода. Заодно добавим удаление, отступы и прочие приятности.
Исходник: places3.xml [21]
Оглядывая свой текст начиная с последнего заголовка, ощущаю явный недостаток пафоса и нескромности — а ведь мы сделали это — научились работать с данными СУБД в сверхтонком клиенте с использованием AJAX и много еще чего. Практически не подозревая об этом.
Интерсистемз предлагает несколько вариантов связей между объектами, живыми из которых являются два — свойство типа объект и отношение "один-ко-многим". Заклинаю вас всем своим опытом работы с Cache' — не используйте ни в коем случае свойства-коллекции объектов, отношения "родитель-потомок" и прочие "реализации отношения один-к-одному". Я лично склонен относить ситуации, когда возникает подобная извращенная необходимость, к огрехам проектирования. Мне тоже жаль труд тех программистов, кто писал реализцию "родителя-потомка", но этот труд был пустой тратой калорий и бюджета. Мусор.
Использование отношений типа "один-ко-многим" и свойств-объектов позволяет просто и универсально решать все проблемы связывания в системе. Все — возьмем к примеру наш цирк.
В объекте "Places" диаграммы мы видим свойство типа "Иностранный внешний ключ" (забудьте о таких, если собираетесь работать с Cache'), именованное "place_type_code", ссылающееся на класс "Ref_Place_Types".
"Ref" как бы указывает на то, что мы имеем дело со справочником, но я противник использования понятия "справочник" — если только мы не имеем дело со справочником мер и весов или таблицами Брадиса. Любой объект, который мы по-глупости обозвали справочником (таблицей справочных значений), в какой-то момент может обрести поведение и справочником быть перестанет — появятся новые свойства и новая логика — и ограничения, накладываемые на т.н. "справочник" могут сильно навредить работе.
Так что просто создадим класс "Тип места представления". Я нажал на нашем place.One в иерархии классов Студии правой кнопкой мыши и выбрал "Копировать", после чего немного поправил код класса. Точно также я создал и интерфейс для работы с типами площадок.
Исходники: type1.xml [22], placeTypes1.xml [23]
В браузере это выглядит так:
Теперь нам нужно определить свойство "Тип" в классе "Место проведения представления". Немного подумав можно прийти к выводу, что для нас нежелательно беспрепятственное удаление типов — хотелось бы чтобы при удалении типа выполнялась проверка, а нет ли мест удаляемого типа. Поскольку логику для этого писать лень, а ограничений на использование отношений не заметно, опишем связь как "один-ко многим". В Студии в классе place.One правой кнопкой мыши выбираем "Добавить" — "Новое свойство".
* Свойства "Places" пока что нет в классе place.Type — поэтому в форме я набрал его руками — Студия позаботится о его создании:
После чего в двух описаниях классов появились блоки отвечающие за отношение "один-ко-многим":
В place.One:
/// Тип площадки
Relationship Type As place.Type [ Cardinality = one, Inverse = Places ];Index TypeIndex On Type;
а в place.Type:
Relationship Places As place.One [ Cardinality = many, Inverse = Type ];
Компилируем.
Для того, чтобы организовать ввод поля "Тип площадки" на интерфейсе, воспользуемся новым zen-контролом (ищите dataCombo после полей ввода):
<text label="Название" dataBinding="Name" />
<text label="Описание" dataBinding="Description" />
<text label="Подробности" dataBinding="Details" />
<dataCombo dataBinding="Type"
sql="select ID,Description from place.Type"
sqlLookup="select Description from place.Type where ID = ?"
/>
В параметре sql мы указали контролу, как предлагать выбор пользователю, а в sqlLookup — как загружать данные из контроллера (например, при выборе новой строки в таблице).
Для отображения в таблице воспользуемся очень мною любимой возможностью неявного JOIN'а посредством "стрелочек":
<tablePane id="placesTable"
tableName="place.One"
onselectrow="zenPage.onSelectPlace()"
valueColumn="ID"
>
<column colName="ID" hidden="true" />
<column header="Название" colName="Name" width="20%"/>
<column header="Описание" colName="Description" width="30%"/>
<column header="Детали" colName="Details" width="30%" />
<column header="Тип" colName="Type" colExpression="Type->Description" />
</tablePane>
Таким же способом можно быстренько создать классы событий и их типов:
Исходники проекта: circus1.xml [24]
Получившийся у меня интерфейс выглядит так:
Наступил момент, когда или нужно честно остановиться и подумать о следующей части или отложить — объем получился неожиданно большим.
Что я хотел сказать о Cache':
Мы получили мощное средство проектирования объектов предметной области, их связей и поведения. Не использовать паттерн "Модель предметной области" при работе с Cache' как минимум нерационально.
ZEN позволяет очень быстро переходить от проектирования БД к реализации GUI, что дает возможность выполнять сотни набросков и прототипов до появления продукта, удовлетворяющего заказчика.
Вчерашний студент воспринимает технологию за несколько дней. Через две недели написанный им код может запросто оказаться в продакшене.
Внесение изменений часто может не ждать очередного релиза — требования пользователя могут быть выполнены в пределах телефонного разговора. Часто пользователю для работы с измененным кодом не приходится использовать даже "F5".
О чем я не успеваю рассказать:
Наследование на уровне хранения — великолепный инструмент, предлагающий различные интерфейсы доступа к одним и тем же данным.
Неявный JOIN. Пример в тексте (и исходниках) есть, но мощь инструмента конечно не раскрыта.
И еще от автора:
Я не просто убежденный лентяй, я проповедник лени. Лениво сделанный код видно сразу — он краток, понятен, и очень эффективно делает именно и только то, для чего предназначен. Последний фактор немаловажен — часто программист обдумывает и пишет универсальный код, участь которого — до конца жизненного цикла системы не получать ровно ничего в запроектированной массе параметров и возвращать только два значения вместо нафантазированных программистом (хуже если аналитиком) сотен. Ленивого программиста также легко отличить — он жизнелюбив и эффективен. Он в курсе светских сплетен и NoSQL-холиваров. Он посещает театры и занимается детьми. Если он программирует, то лишь когда без этого никак не обойтись.
Некоторые утверждают, что заслуга Интерсистемз невелика — главное М-язык, глобалы и прочие радости бэ-деревянного зодчества (в первом варианте я тут опечатался по-фрейду, набрав раБости). Многие из наших программистов работают с Cache' не первый год и вовсе не знают команд работы с глобалами, о ужас!
Заслуга Интерсистемз для меня в том, что они дали возможность забыть о "повседневном М" — предложили использовать его лишь как специю, украшающую вкус совершенно иного блюда, с рецептами которого я и попробовал начать Вас знакомить.
Важная сноска: все вышесказанное неприменимо к Российским стандартам бухгалтерского учета — пресловутому РСБУ, отвратительному примеру того, как не нужно организовывать учет. Никогда не буду писать бухгалтерский софт. Сказал я себе 20 лет назад. Придерживаюсь. Нет в ларьке объекта "проводка"! Есть витрина, продавец, касса. До 22-х часов есть объект "спиртное". Но объекта "проводка" там нет. Разве что электропроводка.
Спасибо за внимание.
Автор: kolesov
Источник [25]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/razrabotka/36567
Ссылки в тексте:
[1] http://www.apache.org/dist/httpd/binaries/win32/: http://www.apache.org/dist/httpd/binaries/win32/
[2] httpd-2.2.22-win32-x86-no_ssl.msi: http://www.apache.org/dist/httpd/binaries/win32/httpd-2.2.22-win32-x86-no_ssl.msi
[3] http://download.intersystems.com/download/: http://download.intersystems.com/download/
[4] http://localhost/csp/samples/ZENDemo.Home.cls: http://localhost/csp/samples/ZENDemo.Home.cls
[5] Library of Free Data Models from DatabaseAnswers.org.: http://www.databaseanswers.org/data_models/index.htm
[6] такую: http://www.databaseanswers.org/data_models/circus/index.htm
[7] Бритва Оккама: http://ru.wikipedia.org/wiki/Бритва_Оккама
[8] Ле Шателье: http://ru.wikipedia.org/wiki/Принцип_Ле_Шателье_—_Брауна
[9] Гейзенберга: http://ru.wikipedia.org/wiki/Принцип_Гейзенберга
[10] Бутерброда: http://ru.wikipedia.org/wiki/Закон_бутерброда
[11] шаблонах проектирования: http://ru.wikipedia.org/wiki/Шаблон_проектирования
[12] конвейер: http://softblog.violet-tape.ru/2012/12/10/pipeline-i/
[13] предметной области: http://martinfowler.com/eaaCatalog/domainModel.html
[14] http://localhost:57772/csp/bs/zui.Places.cls: http://localhost:57772/csp/bs/zui.Places.cls
[15] localhost: http://localhost
[16] "Стандарт настроек безопасности СУБД Intersystems Cache'": http://www.intersystems.ru/cache/education/docs/pci_dss_isc_2012.pdf
[17] places1.xml: https://www.dropbox.com/s/0cqyfrf8vyjz1rd/places1.xml
[18] MVC: http://ru.wikipedia.org/wiki/Model-View-Controller
[19] one1.xml: https://www.dropbox.com/s/rb7yzjcgl800vz5/one1.xml
[20] places2.xml: https://www.dropbox.com/s/ilfj4wgr82i1xgf/places2.xml
[21] places3.xml: https://www.dropbox.com/s/d23rq9mey3kyf8h/places3.xml
[22] type1.xml: https://www.dropbox.com/s/x0tzc5u27uhn1am/type1.xml
[23] placeTypes1.xml: https://www.dropbox.com/s/b6zipgp61w3jych/placeTypes1.xml
[24] circus1.xml: https://www.dropbox.com/s/jpklfmn4atg9wzs/circus1.xml
[25] Источник: http://habrahabr.ru/post/183340/
Нажмите здесь для печати.