Привет, Хаброжители!
Книга Никиты Зайцева aka WildHare — пример того, как можно систематизировать и упаковать в текстовый формат профессиональный опыт, накопленный за почти двадцать пять лет успешной инженерной практики. Познакомьтесь с концепцией разработки прикладного ПО через эффективность процесса на всех стадиях — от работы с ожиданиями и требованиями до сопровождения и технической поддержки. Все приведенные в книге принципы, правила и рекомендации базируются исключительно на личном практическом опыте автора. Книга была написана исходя из девиза, вынесенного в название, — не спеша, эффективно и правильно.
Кому адресована эта книга? В первую очередь она будет интересна профильным специалистам, то есть людям, занятым в отрасли разработки прикладного ПО, как начинающим, так и зрелым профессионалам.
Техническим контекстом в книге является технологический стек «1С» — автор всю свою профессиональную жизнь провел именно в этом уголке IT-вселенной и оперирует областями знания, в которых абсолютно уверен, и готов отвечать за каждое сказанное слово. Но идеи, изложенные в книге, можно применять к любым другим технологическим стекам.
Начать, как это принято в инженерном деле, следует с терминологии, точнее, с разбора физического смысла, заложенного в главный термин.
«Эргономичность» происходит от сочетания греческих корней ἔργον и νόμος. В приблизительном переводе на современный русский получается комбинация «работы», то есть прилагаемых усилий, и «закона», под которым понимаются порядок и правила приложения этих усилий к предмету. В нашем случае предметом является бизнес-приложение, точнее, функциональность бизнес-приложения, а еще точнее, инструментарий декларативного управления этой функциональностью, реализованный в формате экранной формы.
В среде специалистов по разработке бизнес-приложений (да и программного обеспечения вообще) можно встретить мнение, будто эргономичность пользовательского интерфейса определяется в первую очередь удобством для пользователя. Это мнение нельзя, конечно, прямо в лоб назвать ошибочным, но можно и нужно назвать как минимум субъективным — что одному пользователю удобство, другому может показаться каторжной повинностью.
Базировать инженерные методики на столь зыбком фундаменте вряд ли будет разумным. Если мы начнем разбирать удобство с точки зрения практической психологии, мы придем к выводу, что существенная, а возможно, и бˆольшая часть удобства заключается в привыкании к определенной последовательности элементарных действий, которые в дальнейшем можно выполнять с закрытыми глазами, то есть почти автоматически.
Практически неизбежным следствием этого феномена является неприятие значительной частью опытных пользователей абсолютно любых изменений, привносимых в привычный («старый», «добрый», «теплый», «ламповый», <вписать нужное слово>) пользовательский интерфейс, о каком бы классе программных продуктов ни шла речь.
Дело далеко не только в удобстве отдельно взятого пользователя информационной системы, и даже не в удобстве вовсе. Под высокой эргономичностью мы понимаем прежде всего высокий коэффициент полезного действия, демонстрируемый операторами нашего бизнес-приложения при выполнении тех или иных операций с ним. Что важно — в общий зачет идет не только метрологическое время, затраченное оператором на манипуляции с элементами интерфейса, не только количество щелчков кнопками мыши и количество метров, намотанных этой мышью по рабочему столу оператора. И даже совокупным мышечным усилием на перемещение взгляда с одной области на другую общий счет не заканчивается.
Необходимо учитывать интеллектуальное усилие, затраченное пользователем на распознавание интерфейсной идеи, заложенной разработчиком/дизайнером в форму, на планирование необходимой последовательности действий, на чтение и осознание надписей/подписей, на инстинктивную автопроверку «все ли я сделал правильно» и другие сопутствующие ментальные трудозатраты.
Приведем аллегорический пример, очень грубый, но вполне наглядный. Возьмите первую страницу любой главы любой из книжек про Гарри Поттера (например), прочитайте и тут же попробуйте кратко пересказать своими словами. А теперь так же возьмите первую страницу любой главы «Махабхараты» (или «Критики чистого разума», или чего-нибудь в этом роде) и повторите опыт. Объем текста одинаковый, переведено на русский, а вот КПД усилий, затраченных на понимание и усвоение, — немножко разный.
Да, в случае тяжелых философских текстов низкий КПД работы с ними является даже не побочным эффектом, а базовым условием — так и было задумано, читатель должен напрягать мозг. Но если мы оформляем отгрузку, формируем управленческий баланс, управляем грузоперевозками или выписываем квартальную премию продавцам — наши интеллектуальные усилия, затрачиваемые на взаимодействия с информационной системой, должны быть минимальными. Именно такое положение дел применительно к управляемым формам «1С: Предприятия» мы и называем эргономичностью.
Начиная проектировать форму, мы имеем дело с абсолютно чистым листом. Можно считать, что у нас есть своего рода игровая доска, пока еще пустая, и небольшая кучка фигур, каждая из которых изображает реквизит объекта, управляющий элемент, команду и тому подобное.
Наша задача заключается в том, чтобы составить на доске такую комбинацию фигур, работать с которой пользователю будет не только надежно и удобно, но еще и продуктивно, то есть с максимальным коэффициентом полезного действия. Есть разные подходы к решению задачи «распределить заготовленный набор фигурок на пустом игровом поле», но все их можно обобщить до двух принципиально разных — подход художника и подход инженера.
Художник работает по принципу «я так вижу»: процесс никак не систематизирован (или, выразимся мягче, стороннему взгляду не видно никаких признаком систематизации); фигурки многократно перемещаются по полю туда и обратно, иногда по самым неожиданным траекториям; в какой-то момент незаконченный вариант признается негодным, фигурки сметаются с доски, смешиваются в кучу, и процесс входит в следующую итерацию; в какой-то момент процесс прекращается, даже если нескольких фигурок не хватило или какие-то были признаны лишними, фиксируем результат — готово.
Да, так тоже можно. И для каких-то других классов программного обеспечения такой подход может оказаться единственно успешным. Но мы-то проектируем визуальный интерфейс бизнес-приложения, и одним из главных требований к интерфейсу в наших проектных документах явно или неявно обозначено такое свойство, как «единообразие» (оно же «унифицированность»). Обеспечить визуальное и поведенческое единообразие множества экранных форм, используя подход художника, не получится чисто технически, любой художник на третий же день работы объяснит вам, что «вот так» он видел вчера, а сегодня проснулся совсем другим человеком и теперь видит «вот эдак». Прекрасно и полезно в разработке, например, компьютерных игр, но категорически противопоказано бизнес-приложениям.
Подход инженера почти полностью исключает индивидуальное творчество и сводит проектирование очередной экранной формы к предопределенной последовательности шагов и следованию нескольким предопределенным правилам. Да, это совсем не так весело, но зато быстро, предсказуемо, и, главное, в результате мы имеем очень хорошие шансы успешно пройти приемочные испытания.
Там, где художник видит чистый лист (tabula rasa, как говорили наши древние коллеги), инженер видит рабочую область, уже расчерченную на отдельные зоны. Далее инженер сверяется с функциональной спецификацией соответствующего объекта системы, оценивает количество будущих элементов формы и принимает несколько очень простых решений: 1) обычная форма или «мастер»; 2) общая поверхность — страницы или гибрид (верхняя область — общая, нижняя — по страницам); 3) расположение реквизитов в общей области — в одну колонку или две.
Получив ответы, мы аккуратно наносим на наше игровое поле разметку, то есть создаем и настраиваем группы элементов. Определяя взаимное расположение маленьких рабочих областей внутри общей большой (то есть взаимное расположение групп внутри формы), мы придерживаемся принципа газетной верстки. Читатель, в нашем случае пользователь, читает газету/интерфейс в привычном для себя стиле — слева направо до конца строки и далее по строкам сверху вниз. Это если текст сверстан в одну колонку. Если же колонок две — сперва прочитывается левая, затем следует переход снизу вверх вправо — на следующую колонку.
Верстая интерфейс, мы обязательно учитываем, какие из реквизитов/элементов являются основными (важные, обязательные и так далее), а какие — вспомогательными (необязательные, дополняющие, справочные). Важные элементы внутри группы располагаются в верхнем левом углу и выстраиваются сверху вниз — либо в порядке убывания важности, либо в некоем логическом порядке, согласно прикладной специфике объекта. Если группа верстается в две колонки — важные элементы располагаются в левой колонке, а вспомогательные — в правой, и чем менее значимым является элемент, тем ближе его расположение к нижнему правому углу.
Ровно тот же принцип мы задействуем, определяя взаимное расположение самих групп внутри формы/страницы. Здесь, как и в огромном количестве других наших задач, нам помогает декомпозиция — от формы к группе, от группы к элементу. Да, форма получается «квадратно-угловатая», но для бизнес-приложения минималистический стиль является наилучшим выбором.
Разумеется, форму можно украсить какими-либо элементами декора — небольшая картинка, симпатичная надпись-врезка, что-нибудь в этом роде, но это уже следующий уровень дизайнерского мастерства, который требует как минимум художественного вкуса и хотя бы зачатков профильного образования. Мы все-таки компьютерные инженеры, а не иллюстраторы интерфейсов — надежно работающий двигатель для нас гораздо важнее художественного логотипа «с шашечками».
Последнее, на чем стоит акцентировать внимание при работе с группами элементов форм, — у каждой группы должно быть информативное, «говорящее» имя. Даже если группа является строго технической, без отображения заголовка на форме, у нее все равно должно быть правильное имя.
Для чего это нужно? Разработчику это может пригодиться в ситуациях, когда управление элементами формы (например, добавление нового элемента в группу) выполняется программно, через код. В тех далеко не редких случаях, когда «заводской» внешний вид формы по каким-то причинам не устраивает пользователя и ему хочется перекомпоновать форму по-своему, платформа позволяет это сделать. При этом пользователю гораздо приятнее видеть в дереве элементов осмысленные имена вместо безликих Группа321.
Несколько слов про асинхронное выполнение длительных операций уже было сказано ранее, мы не будем их повторять, а обратим внимание на связь между общей эргономичностью пользовательского интерфейса и асинхронностью операций над объектами данных, выполняемых при помощи этого интерфейса.
Что мы понимаем под «длительной операцией»? Термин используется в его естественном значении, нельзя его путать с одноименной подсистемой БСП. Стандарт разработки #642 «Длительные операции на сервере» требует переводить в асинхронный режим все серверные вызовы, выполнение которых «при стандартном сценарии» занимает более 8 секунд.
Почему именно 8 секунд? Стандарт поясняет, что более длительное ожидание может привести к тайм-ауту браузера или веб-сервера, то есть вместо ответа или дальнейшего ожидания пользователь увидит в браузере 504 Gateway Timeout. Это действительно веская причина, но что такое «стандартный сценарий»? Если серверный вызов связан с чтением или записью объектов данных — длительность будет зависеть от текущей нагрузки на СУБД и оборудование; если в рамках серверного вызова выполняется обращение к некой сторонней системе — длительность вызова будет зависеть от времени ее отклика, ну и так далее.
Серверный вызов, который в локальной информационной тестовой базе разработчика гарантированно отрабатывается за две секунды, в реальной нагруженной клиент-серверной информационной базе может зависнуть и на пять секунд, и на десять, и даже на двадцать. Поэтому рекомендуется все-таки считать описанный в стандарте тайм-аут предельно допустимым значением и в реальных задачах разработки ориентироваться на более строгий интервал — например, все, что превышает одну секунду, должно выполняться асинхронно.
Механику длительной операции (а вот здесь уже термин БСП) можно вызывать по-разному, конкретные примеры мы здесь приводить не будем, огромное их количество можно найти в типовых конфигурациях. Но, работая с длительной операцией, важно не забывать, что по другую сторону монитора сидит живой человек и этому человеку очень не по нраву ситуации, когда после команды на выполнение какого-либо действия в течение долгого времени нет никаких визуальных признаков того, что действие не зависло, а выполняется.
Обычно, когда мы говорим об асинхронности, мы имеем в виду определенный способ взаимодействия клиента и сервера, но и внутри клиентского кода можно встретить небольшие, скажем так, вкрапления асинхронного взаимодействия (листинг 5.7).
Листинг 5.7. Типичный пример асинхронного взаимодействия клиентских методов
Для чего используется такая техника кодирования? Оба метода располагаются на стороне клиента, и напрашивается прямой вызов одного из другого. Но следует понимать, что форме требуется время, чтобы скомпоновать, расставить и отрисовать свои элементы. Разница между прямым вызовом соседнего метода и вызовом этого же метода через механику обработки ожидания с интервалом ~100 миллисекунд заключается в том, что во втором случае форма получает эти ~100 миллисекунд для манипуляций с внешним видом своих элементов.
Человеческое восприятие устроено так, что мы, конечно, терпеть не можем длительное пустое ожидание, но и ситуации, когда какие-то элементы окружающего мира не успевают принять правильное положение из-за молниеносности происходящего, нас тоже очень раздражают. Поэтому, чтобы придать изменениям формы определенную плавность, мы и задействуем, казалось бы, бессмысленный однократный обработчик ожидания. Физический смысл такого кода — «выполнение через паузу», именно так его и стоит читать.
Термину «асинхронность» в контексте программного кода управляемых форм платформы «1С: Предприятие» немного не повезло. Дело в том, что под асинхронностью мы прежде всего понимаем физическую асинхронность двух потоков исполнения программного кода, когда в одном потоке мы даем команду на исполнение, а само исполнение происходит в другом потоке. Да, в случае обработчиков ожидания поток исполнения (процесс клиентского приложения) один и тот же, но команда на исполнение кода и само исполнение хотя бы явно разнесены по времени.
Но у технологической платформы есть и свое толкование термина «асинхронность», оно применяется для так называемых асинхронных клиентских функций. Что это такое? У разработчика есть возможность вызвать строго определенные элементарные микроформы интерактивного взаимодействия с пользователем: задать вопрос и получить/обработать ответ; вывести сообщение и получить подтверждение о прочтении; запросить, получить и обработать значение примитивного типа, ну и так далее.
Давным-давно, начиная с самых первых версий платформы, для каждого из этих действий во встроенном языке был предусмотрен соответствующий оператор. Затем появился веб-клиент, и поначалу для вопросов, предупреждений и тому подобного использовались модальные диалоги браузера. Но в какой-то момент разработчики основных браузеров запретили разработчикам веб-приложений использовать модальные диалоги — действительно очень неприятно, когда модальный диалог «Вы уверены? — Да/Нет» блокирует работу со всеми открытыми вкладками.
Чтобы веб-клиент продолжал корректно работать в новых версиях браузеров, в платформу пришлось добавить альтернативный способ работы с простыми интерактивными диалогами. Так и появились «асинхронные клиентские функции».
(В скобках заметим, что если рассматривать реальное исполнение соответствующего программного кода — как оно есть, то асинхронность у «асинхронных клиентских функций» мы сможем найти только в названии; на самом же деле команда на вызов интерактивного диалога и обработка реакции пользователя исполняются последовательно, разница с классическим способом — только в синтаксической конструкции. Но мы в очередной раз просто напомним себе, что неудачных названий не бывает и что совершенно незачем цепляться к словам.)
Синтаксическую эволюцию простых интерактивных диалогов лучше всего показать на несложном примере — вопрос пользователю/обработка ответа. Классический модальный способ приведен в листинге 5.8.
Листинг 5.8. Модальный способ задать вопрос пользователю
Первая версия асинхронных клиентских функций получилась (и да, тавтология здесь уместна) вполне функциональной, но не особенно удобной для написания, чтения и отладки. Листинг 5.9 показывает только один вопрос пользователю, а представьте, если последовательно нужно будет задать несколько вопросов? Код получится, мягко говоря, запутанным.
Листинг 5.9. Первая инкарнация асинхронных клиентских функций
Вторая версия была реализована в платформе версии 3.1.18, и с ней работать уже гораздо проще и приятнее (листинг 5.10).
Листинг 5.10. Вторая инкарнация асинхронных клиентских функций
Правда, перед разработчиком возникает очень серьезный вопрос. Предположим, мы в своем программном коде перейдем на вторую версию. Но что, если мы пишем тиражируемое решение или хотя бы универсальное расширение, которое должно работать на почти любой конфигурации?
Да, можно обозначить минимальные системные требования и даже выставить соответствующий режим совместимости, но вероятность того, что разработчик предпочтет перестраховаться и задействовать «для надежности» старые асинхронные клиентские функции, остается, к сожалению, весьма высокой.
Можно ли здесь порекомендовать стратегию разработки «не боимся задействовать новые возможности платформы, пусть даже кто-то из потенциальных пользователей принципиально работает на устаревших релизах»? Наверное, можно. Понятие «LTS релиза» в нашем сегменте IT-вселенной пока что не прижилось, и далеко не факт, что в этом «не прижилось» есть что-то плохое.
Попытка проследить историю современных бизнес-приложений приведет нас к невероятных объемов «саркофагу», заполненному разнотипными и разноформатными бумажными «формулярами». Причем под «формуляром» мы понимаем абсолютно любой технический артефакт, задействованный в обеспечении деловых процессов. Это может быть что угодно по формату — от берестяной таблички с тремя строчками, которые нацарапаны острым камушком, до многоэтажного здания, плотно набитого гроссбухами, каждая страница которых исписана компактным почерком профессионального бухгалтера.
Электронные формы являются вполне естественным эволюционным продолжением бумажных. Но в отличие от своих дальних предков электронные формы обладают принципиально иным качеством, а именно встроенным поведением. Бумажная форма абсолютно пассивна и никак не может повлиять на действия пользователя, даже если он напишет поперек формы слова, которые обычно произносятся только вслух, бумага все это стерпит.
А вот электронная форма вполне способна не только взаимодействовать с пользователем, но даже играть в этом взаимодействии руководящую, доминирующую роль. Как часто можно услышать от оператора (в банке, кассе, учреждении, да где угодно) что-то вроде: «Если я не введу <вписать нужное>, меня не пустит дальше?» Вот именно. Электронная форма на определенном уровне автоматизации претерпевает нечто вроде фазового перехода и превращается из субъекта управления в полноценного актора (а человек-оператор соответственно движется в строго обратном направлении).
Но мы все-таки компьютерные инженеры, а не представители философской школы «наблюдай-и-рассказывай», мы рассуждаем в парадигме «работает/не работает»; «полезно/бесполезно»; «эффективно/неэффективно» и никак иначе. Поведение экранных форм само по себе не может быть ни плохим, ни хорошим, здесь все зависит от того, как мы спроектируем и запрограммируем это их поведение.
Первое, что приходит в голову любому проектировщику и разработчику, — включить «защиту от дурака». Термин довольно грубый, но устоявшийся и общепринятый. Самый простой случай такой защиты — это банальная проверка реквизитов на заполненность. Если указано хоть какое-то значение, с этим можно работать дальше.
Большую часть таких проверок можно передоверить платформе, выставив для соответствующих реквизитов опцию ПроверкаЗаполнения = Выдавать
Ошибку. Перечень проверяемых реквизитов объекта можно модифицировать программно, для этого в модуле объекта предусмотрен специальный обработчик. Но далеко не всегда можно обойтись простой проверкой на непустое значение.
Самые опасные логические бомбы подкладываются в первичные данные и/или управляющие параметры как раз не пустыми, но совершенно точно некорректными с точки зрения прикладной логики значениями. В таких случаях нам приходится дополнять штатную проверку своей собственной логикой, например, как в листинге 5.11.
Листинг 5.11. Проверка корректности ИНН и СНИЛС перед записью объекта
Следует отдельно отметить два класса ситуаций. Первый класс — когда у нас есть хотя бы приблизительный алгоритм проверки корректности, не изобретенный нами самостоятельно, а подтвержденный каким-либо внешним источником. В приведенном в листинге 5.11 примере мы проверяем ИНН и СНИЛС, для каждого из которых можно вычислить и проверить контрольную сумму. Если же вместо алгоритма у нас есть только интуитивное понимание «в это поле могут случайно ввести мусор, и тогда возникнут проблемы», следует либо проконсультироваться с постановщиком/владельцем задачи, либо вообще не задействовать никакую проверку.
Важным здесь представляется даже не технологический аспект, хотя важен и он, а психологический — ошибка или нелогичность в алгоритме проверки, не позволяющая выполнить операцию, вызывает у пользователя сильное раздражение, а это, в свою очередь, только увеличивает вероятность дальнейших ошибок ввода в исполнении этого раздраженного пользователя.
Самый банальный пример — форма адреса. Поле Улица является строго обязательным; но вот автор настоящего текста живет в таком населенном пункте, где улицы отсутствуют, а есть только номера домов, и что прикажете в это поле ввести? Можно, конечно, написать какую-нибудь ерунду, но что, если эта ерунда потом окажется напечатанной на конверте или ордере и в итоге по этому мусорному адресу не доедет что-то важное? Да, адресные классификаторы — это далеко не простая история, но именно на непростых историях мы обычно и тестируем наши универсальные принципы и правила.
Второй класс ситуаций, который приходит в голову вслед за автоматической проверкой, — автоматическое заполнение тех или иных полей ввода. Такое поведение экранных форм можно только приветствовать, пользователю очень приятно, когда за него выполняют естественную черновую работу. Если у нас есть значения по умолчанию для тех или иных реквизитов и эти значения имеют смысл в контексте операции, действительно, отчего бы и не заполнить соответствующие поля.
Но, как и во всяком благом деле, нужно знать меру и не переходить границы разумного. Например, в некоем документе есть реквизит Склад. При создании нового документа мы можем проверить, сколько в справочнике Склады содержится элементов, не помеченных на удаление. Если найден один-единственный такой элемент, значит, будет логичным подставить в документ именно его. Но у пользователя конкретной информационной базы может быть на этот счет совсем другое мнение.
Мы на позиции разработчика программного кода не знаем и не можем знать всех нюансов ситуации. Может быть, элемент только один, потому что их должно быть два, но второй еще не успели создать. А может быть, кто-то случайно поставил лишнюю пометку удаления. В любом случае, если бы реквизит остался незаполненным (а он является обязательным), мы бы привлекли внимание пользователя и заставили его принять определенное решение. Но поскольку мы сделали все сами, причем тихонько, пользователь мог просто не заметить, что оформляет отгрузку или поступление не на тот склад.
Незваная помощь далеко не всегда является настоящей помощью, и об этом нужно помнить. Какие еще элементы «автосервиса» можно и нужно предусмотреть для относительно сложной формы? Есть мнение, что нелишним будет реализовать нечто вроде автоматической проверки на корректность введенных значений и их взаимное соответствие друг другу. Такую проверку нельзя считать фрагментом «защиты от дурака», поскольку ее результаты имеют рекомендательный, а не блокирующий смысл.
Если у пользователя будет волшебная кнопочка «проверить логичность ввода» (или что-то вроде этого) и по этой кнопочке наша форма сумеет сказать что-нибудь вроде «договору будет назначен срок действия длительностью 272 года, такое значение выглядит подозрительным» — вряд ли пользователь затаит обиду на слишком умный программный механизм.
Более подробно с книгой можно ознакомиться на сайте издательства:
» Оглавление
» Отрывок
По факту оплаты бумажной версии книги на e-mail высылается электронная книга.
Для Хаброжителей скидка 25% по купону — 1С
Книга Никиты Зайцева aka WildHare — пример того, как можно систематизировать и упаковать в текстовый формат профессиональный опыт, накопленный за почти двадцать пять лет успешной инженерной практики. Познакомьтесь с концепцией разработки прикладного ПО через эффективность процесса на всех стадиях — от работы с ожиданиями и требованиями до сопровождения и технической поддержки. Все приведенные в книге принципы, правила и рекомендации базируются исключительно на личном практическом опыте автора. Книга была написана исходя из девиза, вынесенного в название, — не спеша, эффективно и правильно.
Кому адресована эта книга? В первую очередь она будет интересна профильным специалистам, то есть людям, занятым в отрасли разработки прикладного ПО, как начинающим, так и зрелым профессионалам.
Техническим контекстом в книге является технологический стек «1С» — автор всю свою профессиональную жизнь провел именно в этом уголке IT-вселенной и оперирует областями знания, в которых абсолютно уверен, и готов отвечать за каждое сказанное слово. Но идеи, изложенные в книге, можно применять к любым другим технологическим стекам.
Скромное обаяние управляемой формы
Начать, как это принято в инженерном деле, следует с терминологии, точнее, с разбора физического смысла, заложенного в главный термин.
«Эргономичность» происходит от сочетания греческих корней ἔργον и νόμος. В приблизительном переводе на современный русский получается комбинация «работы», то есть прилагаемых усилий, и «закона», под которым понимаются порядок и правила приложения этих усилий к предмету. В нашем случае предметом является бизнес-приложение, точнее, функциональность бизнес-приложения, а еще точнее, инструментарий декларативного управления этой функциональностью, реализованный в формате экранной формы.
В среде специалистов по разработке бизнес-приложений (да и программного обеспечения вообще) можно встретить мнение, будто эргономичность пользовательского интерфейса определяется в первую очередь удобством для пользователя. Это мнение нельзя, конечно, прямо в лоб назвать ошибочным, но можно и нужно назвать как минимум субъективным — что одному пользователю удобство, другому может показаться каторжной повинностью.
Базировать инженерные методики на столь зыбком фундаменте вряд ли будет разумным. Если мы начнем разбирать удобство с точки зрения практической психологии, мы придем к выводу, что существенная, а возможно, и бˆольшая часть удобства заключается в привыкании к определенной последовательности элементарных действий, которые в дальнейшем можно выполнять с закрытыми глазами, то есть почти автоматически.
Практически неизбежным следствием этого феномена является неприятие значительной частью опытных пользователей абсолютно любых изменений, привносимых в привычный («старый», «добрый», «теплый», «ламповый», <вписать нужное слово>) пользовательский интерфейс, о каком бы классе программных продуктов ни шла речь.
Дело далеко не только в удобстве отдельно взятого пользователя информационной системы, и даже не в удобстве вовсе. Под высокой эргономичностью мы понимаем прежде всего высокий коэффициент полезного действия, демонстрируемый операторами нашего бизнес-приложения при выполнении тех или иных операций с ним. Что важно — в общий зачет идет не только метрологическое время, затраченное оператором на манипуляции с элементами интерфейса, не только количество щелчков кнопками мыши и количество метров, намотанных этой мышью по рабочему столу оператора. И даже совокупным мышечным усилием на перемещение взгляда с одной области на другую общий счет не заканчивается.
Необходимо учитывать интеллектуальное усилие, затраченное пользователем на распознавание интерфейсной идеи, заложенной разработчиком/дизайнером в форму, на планирование необходимой последовательности действий, на чтение и осознание надписей/подписей, на инстинктивную автопроверку «все ли я сделал правильно» и другие сопутствующие ментальные трудозатраты.
Приведем аллегорический пример, очень грубый, но вполне наглядный. Возьмите первую страницу любой главы любой из книжек про Гарри Поттера (например), прочитайте и тут же попробуйте кратко пересказать своими словами. А теперь так же возьмите первую страницу любой главы «Махабхараты» (или «Критики чистого разума», или чего-нибудь в этом роде) и повторите опыт. Объем текста одинаковый, переведено на русский, а вот КПД усилий, затраченных на понимание и усвоение, — немножко разный.
Да, в случае тяжелых философских текстов низкий КПД работы с ними является даже не побочным эффектом, а базовым условием — так и было задумано, читатель должен напрягать мозг. Но если мы оформляем отгрузку, формируем управленческий баланс, управляем грузоперевозками или выписываем квартальную премию продавцам — наши интеллектуальные усилия, затрачиваемые на взаимодействия с информационной системой, должны быть минимальными. Именно такое положение дел применительно к управляемым формам «1С: Предприятия» мы и называем эргономичностью.
Северная и Южная группировки элементов
Начиная проектировать форму, мы имеем дело с абсолютно чистым листом. Можно считать, что у нас есть своего рода игровая доска, пока еще пустая, и небольшая кучка фигур, каждая из которых изображает реквизит объекта, управляющий элемент, команду и тому подобное.
Наша задача заключается в том, чтобы составить на доске такую комбинацию фигур, работать с которой пользователю будет не только надежно и удобно, но еще и продуктивно, то есть с максимальным коэффициентом полезного действия. Есть разные подходы к решению задачи «распределить заготовленный набор фигурок на пустом игровом поле», но все их можно обобщить до двух принципиально разных — подход художника и подход инженера.
Художник работает по принципу «я так вижу»: процесс никак не систематизирован (или, выразимся мягче, стороннему взгляду не видно никаких признаком систематизации); фигурки многократно перемещаются по полю туда и обратно, иногда по самым неожиданным траекториям; в какой-то момент незаконченный вариант признается негодным, фигурки сметаются с доски, смешиваются в кучу, и процесс входит в следующую итерацию; в какой-то момент процесс прекращается, даже если нескольких фигурок не хватило или какие-то были признаны лишними, фиксируем результат — готово.
Да, так тоже можно. И для каких-то других классов программного обеспечения такой подход может оказаться единственно успешным. Но мы-то проектируем визуальный интерфейс бизнес-приложения, и одним из главных требований к интерфейсу в наших проектных документах явно или неявно обозначено такое свойство, как «единообразие» (оно же «унифицированность»). Обеспечить визуальное и поведенческое единообразие множества экранных форм, используя подход художника, не получится чисто технически, любой художник на третий же день работы объяснит вам, что «вот так» он видел вчера, а сегодня проснулся совсем другим человеком и теперь видит «вот эдак». Прекрасно и полезно в разработке, например, компьютерных игр, но категорически противопоказано бизнес-приложениям.
Подход инженера почти полностью исключает индивидуальное творчество и сводит проектирование очередной экранной формы к предопределенной последовательности шагов и следованию нескольким предопределенным правилам. Да, это совсем не так весело, но зато быстро, предсказуемо, и, главное, в результате мы имеем очень хорошие шансы успешно пройти приемочные испытания.
Там, где художник видит чистый лист (tabula rasa, как говорили наши древние коллеги), инженер видит рабочую область, уже расчерченную на отдельные зоны. Далее инженер сверяется с функциональной спецификацией соответствующего объекта системы, оценивает количество будущих элементов формы и принимает несколько очень простых решений: 1) обычная форма или «мастер»; 2) общая поверхность — страницы или гибрид (верхняя область — общая, нижняя — по страницам); 3) расположение реквизитов в общей области — в одну колонку или две.
Получив ответы, мы аккуратно наносим на наше игровое поле разметку, то есть создаем и настраиваем группы элементов. Определяя взаимное расположение маленьких рабочих областей внутри общей большой (то есть взаимное расположение групп внутри формы), мы придерживаемся принципа газетной верстки. Читатель, в нашем случае пользователь, читает газету/интерфейс в привычном для себя стиле — слева направо до конца строки и далее по строкам сверху вниз. Это если текст сверстан в одну колонку. Если же колонок две — сперва прочитывается левая, затем следует переход снизу вверх вправо — на следующую колонку.
Верстая интерфейс, мы обязательно учитываем, какие из реквизитов/элементов являются основными (важные, обязательные и так далее), а какие — вспомогательными (необязательные, дополняющие, справочные). Важные элементы внутри группы располагаются в верхнем левом углу и выстраиваются сверху вниз — либо в порядке убывания важности, либо в некоем логическом порядке, согласно прикладной специфике объекта. Если группа верстается в две колонки — важные элементы располагаются в левой колонке, а вспомогательные — в правой, и чем менее значимым является элемент, тем ближе его расположение к нижнему правому углу.
Ровно тот же принцип мы задействуем, определяя взаимное расположение самих групп внутри формы/страницы. Здесь, как и в огромном количестве других наших задач, нам помогает декомпозиция — от формы к группе, от группы к элементу. Да, форма получается «квадратно-угловатая», но для бизнес-приложения минималистический стиль является наилучшим выбором.
Разумеется, форму можно украсить какими-либо элементами декора — небольшая картинка, симпатичная надпись-врезка, что-нибудь в этом роде, но это уже следующий уровень дизайнерского мастерства, который требует как минимум художественного вкуса и хотя бы зачатков профильного образования. Мы все-таки компьютерные инженеры, а не иллюстраторы интерфейсов — надежно работающий двигатель для нас гораздо важнее художественного логотипа «с шашечками».
Последнее, на чем стоит акцентировать внимание при работе с группами элементов форм, — у каждой группы должно быть информативное, «говорящее» имя. Даже если группа является строго технической, без отображения заголовка на форме, у нее все равно должно быть правильное имя.
Для чего это нужно? Разработчику это может пригодиться в ситуациях, когда управление элементами формы (например, добавление нового элемента в группу) выполняется программно, через код. В тех далеко не редких случаях, когда «заводской» внешний вид формы по каким-то причинам не устраивает пользователя и ему хочется перекомпоновать форму по-своему, платформа позволяет это сделать. При этом пользователю гораздо приятнее видеть в дереве элементов осмысленные имена вместо безликих Группа321.
Плавная механика асинхронности
Несколько слов про асинхронное выполнение длительных операций уже было сказано ранее, мы не будем их повторять, а обратим внимание на связь между общей эргономичностью пользовательского интерфейса и асинхронностью операций над объектами данных, выполняемых при помощи этого интерфейса.
Что мы понимаем под «длительной операцией»? Термин используется в его естественном значении, нельзя его путать с одноименной подсистемой БСП. Стандарт разработки #642 «Длительные операции на сервере» требует переводить в асинхронный режим все серверные вызовы, выполнение которых «при стандартном сценарии» занимает более 8 секунд.
Почему именно 8 секунд? Стандарт поясняет, что более длительное ожидание может привести к тайм-ауту браузера или веб-сервера, то есть вместо ответа или дальнейшего ожидания пользователь увидит в браузере 504 Gateway Timeout. Это действительно веская причина, но что такое «стандартный сценарий»? Если серверный вызов связан с чтением или записью объектов данных — длительность будет зависеть от текущей нагрузки на СУБД и оборудование; если в рамках серверного вызова выполняется обращение к некой сторонней системе — длительность вызова будет зависеть от времени ее отклика, ну и так далее.
Серверный вызов, который в локальной информационной тестовой базе разработчика гарантированно отрабатывается за две секунды, в реальной нагруженной клиент-серверной информационной базе может зависнуть и на пять секунд, и на десять, и даже на двадцать. Поэтому рекомендуется все-таки считать описанный в стандарте тайм-аут предельно допустимым значением и в реальных задачах разработки ориентироваться на более строгий интервал — например, все, что превышает одну секунду, должно выполняться асинхронно.
Механику длительной операции (а вот здесь уже термин БСП) можно вызывать по-разному, конкретные примеры мы здесь приводить не будем, огромное их количество можно найти в типовых конфигурациях. Но, работая с длительной операцией, важно не забывать, что по другую сторону монитора сидит живой человек и этому человеку очень не по нраву ситуации, когда после команды на выполнение какого-либо действия в течение долгого времени нет никаких визуальных признаков того, что действие не зависло, а выполняется.
Обычно, когда мы говорим об асинхронности, мы имеем в виду определенный способ взаимодействия клиента и сервера, но и внутри клиентского кода можно встретить небольшие, скажем так, вкрапления асинхронного взаимодействия (листинг 5.7).
Листинг 5.7. Типичный пример асинхронного взаимодействия клиентских методов
&НаКлиенте
Процедура ПриОткрытии(Отказ)
Если ЗаполнитьПриОткрытии Тогда
ПодключитьОбработчикОжидания("ЗаполнитьДанныеФормыНаКлиенте",
0.1, Истина);
ЗаполнитьПриОткрытии = Ложь;
Модифицированность = Истина;
КонецЕсли;
КонецПроцедуры
Для чего используется такая техника кодирования? Оба метода располагаются на стороне клиента, и напрашивается прямой вызов одного из другого. Но следует понимать, что форме требуется время, чтобы скомпоновать, расставить и отрисовать свои элементы. Разница между прямым вызовом соседнего метода и вызовом этого же метода через механику обработки ожидания с интервалом ~100 миллисекунд заключается в том, что во втором случае форма получает эти ~100 миллисекунд для манипуляций с внешним видом своих элементов.
Человеческое восприятие устроено так, что мы, конечно, терпеть не можем длительное пустое ожидание, но и ситуации, когда какие-то элементы окружающего мира не успевают принять правильное положение из-за молниеносности происходящего, нас тоже очень раздражают. Поэтому, чтобы придать изменениям формы определенную плавность, мы и задействуем, казалось бы, бессмысленный однократный обработчик ожидания. Физический смысл такого кода — «выполнение через паузу», именно так его и стоит читать.
Предопределенная механика асинхронности
Термину «асинхронность» в контексте программного кода управляемых форм платформы «1С: Предприятие» немного не повезло. Дело в том, что под асинхронностью мы прежде всего понимаем физическую асинхронность двух потоков исполнения программного кода, когда в одном потоке мы даем команду на исполнение, а само исполнение происходит в другом потоке. Да, в случае обработчиков ожидания поток исполнения (процесс клиентского приложения) один и тот же, но команда на исполнение кода и само исполнение хотя бы явно разнесены по времени.
Но у технологической платформы есть и свое толкование термина «асинхронность», оно применяется для так называемых асинхронных клиентских функций. Что это такое? У разработчика есть возможность вызвать строго определенные элементарные микроформы интерактивного взаимодействия с пользователем: задать вопрос и получить/обработать ответ; вывести сообщение и получить подтверждение о прочтении; запросить, получить и обработать значение примитивного типа, ну и так далее.
Давным-давно, начиная с самых первых версий платформы, для каждого из этих действий во встроенном языке был предусмотрен соответствующий оператор. Затем появился веб-клиент, и поначалу для вопросов, предупреждений и тому подобного использовались модальные диалоги браузера. Но в какой-то момент разработчики основных браузеров запретили разработчикам веб-приложений использовать модальные диалоги — действительно очень неприятно, когда модальный диалог «Вы уверены? — Да/Нет» блокирует работу со всеми открытыми вкладками.
Чтобы веб-клиент продолжал корректно работать в новых версиях браузеров, в платформу пришлось добавить альтернативный способ работы с простыми интерактивными диалогами. Так и появились «асинхронные клиентские функции».
(В скобках заметим, что если рассматривать реальное исполнение соответствующего программного кода — как оно есть, то асинхронность у «асинхронных клиентских функций» мы сможем найти только в названии; на самом же деле команда на вызов интерактивного диалога и обработка реакции пользователя исполняются последовательно, разница с классическим способом — только в синтаксической конструкции. Но мы в очередной раз просто напомним себе, что неудачных названий не бывает и что совершенно незачем цепляться к словам.)
Синтаксическую эволюцию простых интерактивных диалогов лучше всего показать на несложном примере — вопрос пользователю/обработка ответа. Классический модальный способ приведен в листинге 5.8.
Листинг 5.8. Модальный способ задать вопрос пользователю
&НаКлиенте
Процедура ВыполнитьОперацию()
ТекстВопроса = "Действительно выполнить операцию?";
Режим = РежимДиалогаВопрос.ДаНет;
Ответ = Вопрос(ТекстВопроса, Режим);
Если Ответ = КодВозвратаДиалога.Да Тогда
ВыполнитьОперациюНаСервере();
КонецЕсли;
КонецПроцедуры // ВыполнитьОперацию()
Первая версия асинхронных клиентских функций получилась (и да, тавтология здесь уместна) вполне функциональной, но не особенно удобной для написания, чтения и отладки. Листинг 5.9 показывает только один вопрос пользователю, а представьте, если последовательно нужно будет задать несколько вопросов? Код получится, мягко говоря, запутанным.
Листинг 5.9. Первая инкарнация асинхронных клиентских функций
&НаКлиенте
Процедура ВыполнитьОперацию()
ТекстВопроса = "Действительно выполнить операцию?";
Описание = Новый ОписаниеОповещения
("ПодтвердитьВыполнениеОперации",
ЭтотОбъект);
Режим = РежимДиалогаВопрос.ДаНет;
ПоказатьВопрос(Описание, ТекстВопроса, Режим);
КонецПроцедуры // ВыполнитьОперацию()
&НаКлиенте
Процедура ПодтвердитьВыполнениеОперации(Ответ, ДопПараметры) Экспорт
Если Ответ = КодВозвратаДиалога.Да Тогда
ВыполнитьОперациюНаСервере();
КонецЕсли;
КонецПроцедуры // ПодтвердитьВыполнениеОперации()
Вторая версия была реализована в платформе версии 3.1.18, и с ней работать уже гораздо проще и приятнее (листинг 5.10).
Листинг 5.10. Вторая инкарнация асинхронных клиентских функций
&НаКлиенте
Асинх Процедура ВыполнитьОперациюАсинх()
ТекстВопроса = "Действительно выполнить операцию?";
Режим = РежимДиалогаВопрос.ДаНет;
ОбещаниеОтвета = ВопросАсинх(ТекстВопроса, Режим);
Ответ = Ждать ОбещаниеОтвета;
Если Ответ = КодВозвратаДиалога.Да Тогда
ВыполнитьОперациюНаСервере();
КонецЕсли;
КонецПроцедуры // ВыполнитьОперациюАсинх()
Правда, перед разработчиком возникает очень серьезный вопрос. Предположим, мы в своем программном коде перейдем на вторую версию. Но что, если мы пишем тиражируемое решение или хотя бы универсальное расширение, которое должно работать на почти любой конфигурации?
Да, можно обозначить минимальные системные требования и даже выставить соответствующий режим совместимости, но вероятность того, что разработчик предпочтет перестраховаться и задействовать «для надежности» старые асинхронные клиентские функции, остается, к сожалению, весьма высокой.
Можно ли здесь порекомендовать стратегию разработки «не боимся задействовать новые возможности платформы, пусть даже кто-то из потенциальных пользователей принципиально работает на устаревших релизах»? Наверное, можно. Понятие «LTS релиза» в нашем сегменте IT-вселенной пока что не прижилось, и далеко не факт, что в этом «не прижилось» есть что-то плохое.
Автозаполнение, автопроверка и другие услуги автосервисов
Попытка проследить историю современных бизнес-приложений приведет нас к невероятных объемов «саркофагу», заполненному разнотипными и разноформатными бумажными «формулярами». Причем под «формуляром» мы понимаем абсолютно любой технический артефакт, задействованный в обеспечении деловых процессов. Это может быть что угодно по формату — от берестяной таблички с тремя строчками, которые нацарапаны острым камушком, до многоэтажного здания, плотно набитого гроссбухами, каждая страница которых исписана компактным почерком профессионального бухгалтера.
Электронные формы являются вполне естественным эволюционным продолжением бумажных. Но в отличие от своих дальних предков электронные формы обладают принципиально иным качеством, а именно встроенным поведением. Бумажная форма абсолютно пассивна и никак не может повлиять на действия пользователя, даже если он напишет поперек формы слова, которые обычно произносятся только вслух, бумага все это стерпит.
А вот электронная форма вполне способна не только взаимодействовать с пользователем, но даже играть в этом взаимодействии руководящую, доминирующую роль. Как часто можно услышать от оператора (в банке, кассе, учреждении, да где угодно) что-то вроде: «Если я не введу <вписать нужное>, меня не пустит дальше?» Вот именно. Электронная форма на определенном уровне автоматизации претерпевает нечто вроде фазового перехода и превращается из субъекта управления в полноценного актора (а человек-оператор соответственно движется в строго обратном направлении).
Но мы все-таки компьютерные инженеры, а не представители философской школы «наблюдай-и-рассказывай», мы рассуждаем в парадигме «работает/не работает»; «полезно/бесполезно»; «эффективно/неэффективно» и никак иначе. Поведение экранных форм само по себе не может быть ни плохим, ни хорошим, здесь все зависит от того, как мы спроектируем и запрограммируем это их поведение.
Первое, что приходит в голову любому проектировщику и разработчику, — включить «защиту от дурака». Термин довольно грубый, но устоявшийся и общепринятый. Самый простой случай такой защиты — это банальная проверка реквизитов на заполненность. Если указано хоть какое-то значение, с этим можно работать дальше.
Большую часть таких проверок можно передоверить платформе, выставив для соответствующих реквизитов опцию ПроверкаЗаполнения = Выдавать
Ошибку. Перечень проверяемых реквизитов объекта можно модифицировать программно, для этого в модуле объекта предусмотрен специальный обработчик. Но далеко не всегда можно обойтись простой проверкой на непустое значение.
Самые опасные логические бомбы подкладываются в первичные данные и/или управляющие параметры как раз не пустыми, но совершенно точно некорректными с точки зрения прикладной логики значениями. В таких случаях нам приходится дополнять штатную проверку своей собственной логикой, например, как в листинге 5.11.
Листинг 5.11. Проверка корректности ИНН и СНИЛС перед записью объекта
&НаКлиенте
Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)
// Проверяем корректность введенного ИНН при создании нового элемента
// справочника ФизическиеЛица (задействуем уже реализованный
// в конфигурации ЗУП алгоритм проверки).
ЗначениеРеквизита = Элементы["ФизлицоИНН"].ТекстРедактирования;
ЗначениеПроверки = СокрЛП(ЗначениеРеквизита);
РеквизитПустой = ПустаяСтрока(ЗначениеПроверки);
Если РеквизитПустой Тогда
Комментарий = "Не заполнено поле ИНН.";
ОбщегоНазначенияКлиент.СообщитьПользователю(Комментарий,
"Элементы.ФизлицоИНН","ФизическоеЛицо.ИНН");
Отказ = Истина;
Возврат;
КонецЕсли;
ФлагОтказаИНН = Не
РегламентированныеДанныеКлиентСервер.ИННСоответствуетТребованиям(
Элементы.ФизлицоИНН.ТекстРедактирования, Ложь, "");
Если ФлагОтказаИНН Тогда
Комментарий = "Указанное значение не является корректным ИНН.";
ОбщегоНазначенияКлиент.СообщитьПользователю(
Комментарий,,"Элементы.ФизлицоИНН","ФизическоеЛицо.ИНН");
Отказ = Истина;
Возврат;
КонецЕсли;
КонецПроцедуры // ПередЗаписью()
Следует отдельно отметить два класса ситуаций. Первый класс — когда у нас есть хотя бы приблизительный алгоритм проверки корректности, не изобретенный нами самостоятельно, а подтвержденный каким-либо внешним источником. В приведенном в листинге 5.11 примере мы проверяем ИНН и СНИЛС, для каждого из которых можно вычислить и проверить контрольную сумму. Если же вместо алгоритма у нас есть только интуитивное понимание «в это поле могут случайно ввести мусор, и тогда возникнут проблемы», следует либо проконсультироваться с постановщиком/владельцем задачи, либо вообще не задействовать никакую проверку.
Важным здесь представляется даже не технологический аспект, хотя важен и он, а психологический — ошибка или нелогичность в алгоритме проверки, не позволяющая выполнить операцию, вызывает у пользователя сильное раздражение, а это, в свою очередь, только увеличивает вероятность дальнейших ошибок ввода в исполнении этого раздраженного пользователя.
Самый банальный пример — форма адреса. Поле Улица является строго обязательным; но вот автор настоящего текста живет в таком населенном пункте, где улицы отсутствуют, а есть только номера домов, и что прикажете в это поле ввести? Можно, конечно, написать какую-нибудь ерунду, но что, если эта ерунда потом окажется напечатанной на конверте или ордере и в итоге по этому мусорному адресу не доедет что-то важное? Да, адресные классификаторы — это далеко не простая история, но именно на непростых историях мы обычно и тестируем наши универсальные принципы и правила.
Второй класс ситуаций, который приходит в голову вслед за автоматической проверкой, — автоматическое заполнение тех или иных полей ввода. Такое поведение экранных форм можно только приветствовать, пользователю очень приятно, когда за него выполняют естественную черновую работу. Если у нас есть значения по умолчанию для тех или иных реквизитов и эти значения имеют смысл в контексте операции, действительно, отчего бы и не заполнить соответствующие поля.
Но, как и во всяком благом деле, нужно знать меру и не переходить границы разумного. Например, в некоем документе есть реквизит Склад. При создании нового документа мы можем проверить, сколько в справочнике Склады содержится элементов, не помеченных на удаление. Если найден один-единственный такой элемент, значит, будет логичным подставить в документ именно его. Но у пользователя конкретной информационной базы может быть на этот счет совсем другое мнение.
Мы на позиции разработчика программного кода не знаем и не можем знать всех нюансов ситуации. Может быть, элемент только один, потому что их должно быть два, но второй еще не успели создать. А может быть, кто-то случайно поставил лишнюю пометку удаления. В любом случае, если бы реквизит остался незаполненным (а он является обязательным), мы бы привлекли внимание пользователя и заставили его принять определенное решение. Но поскольку мы сделали все сами, причем тихонько, пользователь мог просто не заметить, что оформляет отгрузку или поступление не на тот склад.
Незваная помощь далеко не всегда является настоящей помощью, и об этом нужно помнить. Какие еще элементы «автосервиса» можно и нужно предусмотреть для относительно сложной формы? Есть мнение, что нелишним будет реализовать нечто вроде автоматической проверки на корректность введенных значений и их взаимное соответствие друг другу. Такую проверку нельзя считать фрагментом «защиты от дурака», поскольку ее результаты имеют рекомендательный, а не блокирующий смысл.
Если у пользователя будет волшебная кнопочка «проверить логичность ввода» (или что-то вроде этого) и по этой кнопочке наша форма сумеет сказать что-нибудь вроде «договору будет назначен срок действия длительностью 272 года, такое значение выглядит подозрительным» — вряд ли пользователь затаит обиду на слишком умный программный механизм.
Об авторе
Никита Викторович Зайцев (a. k. a. WildHare) — инженер по разработке/эксплуатации автоматизированных систем управления информацией, имеет сертификат 1С «Эксперт по технологическим вопросам крупных внедрений».
За 25 лет профессиональной деятельности прошел путь от программиста-разработчика до технического директора и системного архитектора. Работал в разных прикладных областях — от самых простых до систем «уровня города». Например, участвовал в проекте внедрения УАИС БУ «Облачная бухгалтерия города Москвы», был архитектором и ведущим разработчиком облачной подсистемы «1С: Фреш».
В течение почти всей карьеры сочетал производственные задачи и публицистическую деятельность в области IT: был ведущим популярного технического сайта, вел блог, опубликовал более десятка статей в журнале PC Magazine.
В последнее время занимался консультированием и преподавательской деятельностью (в том числе в МФТИ и ВШЭ). Вел технический подкаст «Радио 1С Энтерпрайз» (t.me/radio1c).
________________________________________________________________________________
Ушел из жизни высококлассный профессионал, талантливый разработчик Никита Зайцев.
В издательстве «Питер» вышла его книга «Путь 1С-разработки. Не спеша, эффективно и правильно».
Работа Никиты Зайцева представляет собой яркий пример того, как можно систематизировать и упаковать в текстовый формат профессиональный опыт, накопленный за почти двадцать пять лет успешной инженерной практики.
Мы приносим соболезнования родным, близким и коллегам Никиты Зайцева.
За 25 лет профессиональной деятельности прошел путь от программиста-разработчика до технического директора и системного архитектора. Работал в разных прикладных областях — от самых простых до систем «уровня города». Например, участвовал в проекте внедрения УАИС БУ «Облачная бухгалтерия города Москвы», был архитектором и ведущим разработчиком облачной подсистемы «1С: Фреш».
В течение почти всей карьеры сочетал производственные задачи и публицистическую деятельность в области IT: был ведущим популярного технического сайта, вел блог, опубликовал более десятка статей в журнале PC Magazine.
В последнее время занимался консультированием и преподавательской деятельностью (в том числе в МФТИ и ВШЭ). Вел технический подкаст «Радио 1С Энтерпрайз» (t.me/radio1c).
________________________________________________________________________________
Ушел из жизни высококлассный профессионал, талантливый разработчик Никита Зайцев.
В издательстве «Питер» вышла его книга «Путь 1С-разработки. Не спеша, эффективно и правильно».
Работа Никиты Зайцева представляет собой яркий пример того, как можно систематизировать и упаковать в текстовый формат профессиональный опыт, накопленный за почти двадцать пять лет успешной инженерной практики.
Мы приносим соболезнования родным, близким и коллегам Никиты Зайцева.
Более подробно с книгой можно ознакомиться на сайте издательства:
» Оглавление
» Отрывок
По факту оплаты бумажной версии книги на e-mail высылается электронная книга.
Для Хаброжителей скидка 25% по купону — 1С