Uncategorized

Автовокзал: мобильное приложение для покупки билетов на пригородные автобусы

С момента основания в 1939 году барнаульский автовокзал значительно шагнул вперед. Теперь это – не просто маленькая станция с тремя лавочками, парой ларьков и кассами, а целый комплекс для обслуживания пассажиров с развитой инфраструктурой. Но для окончательного «осовременивания» ему не хватало одной важной детали – мобильного приложения, позволяющего максимально модернизировать процесс покупки и продажи билетов. Разработка такого приложения, с помощью которого можно быстро и безболезненно покупать билеты в пригородные автобусы до любой точки Алтайского края и близлежащих регионов, и стала одной из наших задач.

 

Автобус – идеальный вариант для путешествий в соседние города. А откуда междугородние автобусы Барнаула отправляются в путь? Правильно, с автовокзала, расположенного на площади Победы.

Вокзал имеет разветвленную сеть автобусных сообщений со всеми городами и районами Алтайского края и соседями: Республикой Алтай, Новосибирской, Кемеровской, Томской областями. Регулярно автобусы ездят и в города Казахстана: Павлодар, Семипалатинск, Усть-Каменогорск, Караганда, Риддер, Бишкек.

Более 300 автобусов выезжают с вокзала ежедневно, а в отдельные дни – более 400. Максимальный среднесуточный объем перевозок – 6000 человек.

Современному автовокзалу – современные способы продажи билетов. Как раз для этой цели нам и нужно было разработать мобильное приложение под Android.

Задача

Идея приложения – помочь жителям региона покупать билеты из любой точки мира, прямо со смартфона или планшета или дома с компьютера.

Быстро, удобно и самое главное – без раздражающих очередей и лишней траты времени.

Такое приложение должно уметь:

  • искать автобусные маршруты, которые идут из населенных пунктов Алтайского края,
  • маршруты следования;
  • бронировать несколько билетов одновременно,
  • продавать багажные билеты,
  • продавать билеты с оплатой банковской картой,
  • позволять просматривать купленные и забронированные билеты,
  • отменять заказы и возвращать деньги на банковскую карту,
  • составлять списки пассажиров (с заполненными данными) для быстрой продажи билетов,
  • сохранять истории поиска маршрутов с возможностью их повторения.

Разработка

Приложение интегрировано сразу с двумя крупными системами – E-traffic и Gateline.net.

Для чего?

  • E-traffic – единый протокол, связанный с Глобальной дистрибьюторской системой (GDS), откуда приложение берет данные по расписанию, билетам, маршрутам и так далее.
  • Gateline.net – платежный шлюз, который обеспечивает связь с банком. Благодаря ему можно оплатить билет любой картой.

Интеграция проходила по API.

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

С интеграцией особых сложностей не возникло, хотя тут мы изрядно повозились с унификацией данных. В отличие от РЖД, база данных для автовокзалов плохо структурирована – каждый хранит информацию так, как хочет. Поэтому денно и нощно мы прописывали и структурировали нужные поля и столбцы, чтоб привести базу данных к единому общему виду.

E-traffic

Но самый эпик случился под конец разработки. Мы думали, что пользователь будет просто показывать билет кондуктору и все. Но по правилам перевозок оказалось, что нужна бумажная копия. Так говорит Закон. Из-за этого просчета нам пришлось потанцевать с бубном и изобрести следующие вещи.

Танцы с бубном понадобились, потому что здесь все не так просто. Прежде всего, пользователю через приложение надо каким-то образом сообщить, что он должен обязательно распечатать билет. Плюс pdf-файл тоже внес свою лепту: как создать возможность для его скачивания из приложения и отправки пользователю на электронную почту.

Поэтому добавили документ «Правила перевозки пассажиров» и специальную кнопку для подтверждения согласия с правилами (Закон о персональных данных, привет), экран со строчкой для электронного адреса и предупреждением о необходимости распечатки, кнопку «Скачать билеты» во всплывающем меню раздела «Билеты».

Успешная покупка билета Управление заказом

В итоге проблему решили.

Принцип работы

Функционал «Автовокзала» реализован в виде интуитивного и понятного меню, в которое входят такие разделы как «Расписание», «Билеты», «Избранное», «История», «Список пассажиров» и «Настройки».

Функционал приложения

Когда пользователь заходит в приложение и заполняет поля: пункт отправления и пункт назначения, пассажиры и билет, в GDS-систему отправляется запрос. Затем на телефон приходит уведомление о его наличии или отсутствии.

Данные пассажира Сохранение данных пассажира

После операции с оплатой пользователь получает билет на телефон. Теперь осталось собрать чемоданы – и в путь!

Важно! Для посадки нужно распечатать билет и показать документ, удостоверяющий личность, который использовался для покупки билета. Без этого останетесь с поклажей на вокзале.

Заказ сохранен

В приложении предусмотрена еще одна замечательная функция, чтобы окончательно облегчить процесс и точно избавить пользователей от необходимости идти на вокзал до отъезда – возврат билетов. Главное – успеть сделать это до отправления автобуса. После пары нажатий деньги вернутся на банковскую карту.

Возврат билета

Но так можно только до отправления автобуса. Если очухались после – то возврат уже в кассе автовокзала.

Дизайн

Над дизайном приложения поколдовали несколько подольше. Он прошел целую эволюцию: от тяжеловатого и нагруженного лишними элементами в начале до легкого и лаконичного в конце.

С интерфейса, как с луковицы, слой за слоем убирали лишнее, пока не остались наиболее важные элементы.

Макеты дизайна Макеты дизайна Макеты дизайна

Макеты первоначального дизайна

Значительно переделали главный экран, меню и иконку.

Первоначальный дизайн

Первоначальный дизайн

Иконка, пожалуй, претерпела больше всего трансформаций и изменилась радикально.

Первый вариант – простой и схематичный.

Иконка - схема

Потом иконка все усложнялась, пока не превратилась в ультрасовременный крупногабаритный автобус с мощными фарами и зеркалами заднего вида. На нем и решили остановиться.

Второй вариант иконки

Третий вариант

Финальная иконка

Хотя, надо признать, все варианты иконок достойны внимания, и схематичная, и мультяшная красная. Но выбрали последний, так как он выглядит более солидно и дорого.

Финальный дизайн

Интересно реализовали и календарь – функциональный элемент, который благодаря всем этим изыскам стал дизайнерским.

В системе E-traffic билеты известны только на ближайшие 20 дней, поэтому отмели вариант с выпадающим календарем на весь месяц. Вместо этого – однострочная разбивка на две недели с навигацией по стрелкам. Календарь как будто есть, но как будто и нет.

Макет календаря

Макет календаря

Календарь

Окончательный вариант календаря

Все выполнено в спокойных тонах морской волны, приятных для глаз.

Готовый проект

Пункты отправления приложения ограничены Алтайским краем, пункты назначения – только вашим воображением и финансами.

С помощью приложения билет можно купить куда угодно – было бы желание!

В добрый путь!

Доступно в Google Play

Как приручить дракона

Объектно-ориентированное проектирование эпохи Средневековья

Пока все обсуждали седьмой сезон «Игры престолов», и пребывали в шоке от того, как Дейенерис научилась управлять своими драконами, мы продолжали коллективно учиться обуздывать наших собственных «IT-драконов» – разработка, управление проектами, маркетинг.

На одном из семинаров мы обсудили интригующую тему – проблемно-ориентированное проектирование (DDD: Domain Driven Design). Так как она обширная и многогранная, то по итогам семинара мы решили не ограничиваться обычными тезисами, а перенеслись в средние века и сочинили легенду о драконах и викингах, которая бы все это проиллюстрировала.

Итак, дети мои, внимаем, запоминаем…

Легенда

Во времена раннего средневековья, во времена древних богов, воителей и королей, когда магические существа еще не исчезли с лица Земли, викинги и драконы страшно враждовали.

Тогда на свете водилось много разных драконов. Одни, большие и мрачные, парили в небесах как огромные грозные птицы и строили гнезда на вершинах утесов. Другие, мелкие и проворные, сновали дружными стайками и ловили крыс и мышей. Третьи жили в глубине морей и были в двадцать раз крупнее синего кита, и выходили на сушу только поохотиться. Но в основном они обитали в Драконьей пустоши, где можно было встретить драконов всех мастей.

Это была ужасная кровавая вражда. Драконы сжигали дома викингов, уносили девушек, продукты и скот. Викинги тоже в долгу не оставались – отлавливали драконов и жестоко расправлялись с ними, а из их шкур изготавливали свое обмундирование.

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

Проблемно-ориентированное проектирование – это методология решения сложных бизнес-задач. В этом случае сложной бизнес-задачей была организация жизни племени и их взаимодействия с драконами.

Domain Driven Design держится на трех столпах – предметная область (Domain), единый язык (Ubiquitous Language) и ограниченный контекст (Bounded Context).

 

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

***

Семь поколений викингов жили в состоянии непрекращающейся борьбы, но ход вещей переломила история, случившаяся с сыном вождя племени, которое именовали как «Мудрое».

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

Эта непохожесть мешала ему стать своим в своем собственном племени, и поэтому у него совсем не было друзей.

Сам вождь не гордился своим сыном. Да и чем гордиться? Физическая сила и умение грамотно атаковать были в цене среди викингов. Высокий интеллект и душевная мягкость, напротив, были совсем ненужными качествами.

Однако юноша был уверен, что как только ему исполнится 18 и он уничтожит одну из рептилий, жизнь наладится. Эйнар старательно тренировался, чтобы с достоинством пройти обряд инициации. Но у него так ничего и не получалось. Меч валился из рук, ноги подкашивались, и он не выиграл ни одного поединка.

***

День инициации неминуемо приближался, и курсы укрощения драконов становились все интенсивнее. Но все было безуспешно – Эйнар по-прежнему одерживал поражение за поражением.

Когда он проиграл очередной поединок, вождь вызвал его на серьезный разговор.

– Сын мой…
– Да, отец.
– Ты же понимаешь важность предстоящего события?
– Да, конечно, отец.
– Тогда почему ты совсем не стараешься?
– Стараюсь, отец. Но я не понимаю, зачем мне убивать дракона. Мне их жалко. Ведь они тоже живые существа.
– Ты не понимаешь! Ты не представляешь, что испытываю я! Думаешь, я хочу изгонять из племени родного сына?! А если я сам нарушу многовековые традиции – то какой я тогда вождь? Тогда меня самого надо изгонять!

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

Сын мой, – продолжил вождь, – мы ведь от тебя не требуем ничего невозможного. Победи дракона – и дальше читай свои книжки. Вот, смотри:

  1. Есть дракон.
  2. Дракон обитает в Драконьей пустоши.
  3. Берешь копье.
  4. Точишь копье.
  5. Надеваешь доспехи.
  6. Идешь в Драконью пустошь.
  7. Находишь дракона (можно некрупного).
  8. Целишься в него копьем.
  9. Убиваешь дракона.
  10. Приносишь тушу в племя.

И все! – заключил вождь.

Пример реализации нескольких ограниченных контекстов – разговор отца и сына о драконах. Для вождя драконы – враги, жуткие огнедышащие твари, которых нужно уничтожить, а также способ сохранить многовековые традиции. Для сына же драконы – милые безобидные существа, с которыми нужно подружиться.

Тут же встала проблема и единого языка – отец и сын говорили на разных языках. Так, снова неправильно построенная модель предметной области усложнила использование единого языка. Если бы такое произошло не в средневековье, а во время разработки проекта, то вряд ли он был бы доведен до конца.

Это про стратегические модели. Что касается тактических, то дракон здесь выступает Сущностью (Entity), Драконья пустошь – Агрегатом (Aggregate), то есть группой связанных сущностей объектов, а стая драконов, живущих в ней, – Хранилищем (Repository).

 

Один из нерушимых принципов DDD – разбивать сложную задачу на несколько простых этапов, чтобы сделать ее максимально быстро и достичь лучшего результата. Это мы видим, когда отец по пунктам объясняет сыну, какие шаги надо предпринять, чтобы убить дракона.

 

***
Наконец, наступил день X.

С самого утра лил дождь, предвещая беду.

Громко прозвучали трубы, что означало – обряду инициации дан старт.

Обряд предстояло пройти пяти мальчикам племени Мудрое.

Вождь произнес торжественную речь.

«Дорогие мои юные воины! Поздравляю вас с этим важным днем! Именно сегодня вы докажете, что достойны быть частью нашего клана! Вперед, в бой!».

 

После удара гонга группа «инициируемых» направилась через лес в Драконью пустошь.

***

По дороге Эйнар размышлял:

  • Что я знаю о драконах? Живут в Драконьей пустоши, питаются овцами, коровами и другим скотом. Перед тем, как приступить к еде, они поджаривают ее своим огненным дыханием.
  • Покрыты толстой чешуей, которую трудно пробить.
  • Примерные размеры – 10 метров в длину, размах крыльев – 10,2 метра, площадь крыльев – 17,5 квадратного метра.
  • Согласно древней истории, которую я прочитал в книге Предков, драконы и люди раньше не воевали друг с другом, а жили в мире. Почему же мы так не можем?
  • Нас пять человек. Значит, пять драконов будет убито. Нет, своего я убивать не буду. Пусть хоть одной жертвой будет меньше.

Любое действие по DDD начинается с переработки знаний. Что и сделал Эйнар по дороге в Драконью пустошь – он проанализировал свои собственные знания, входные данные о летающих рептилиях, информацию из книги Предков и выявил сущность «Дракон», определив для себя другую модель поведения, которая на его взгляд казалось более понятной и эффективной.

 

Вдруг раздался рев, что означало, что отряд пришел в Драконью пустошь.

***
Собратья Эйнара разбрелись по пустоши в поисках драконов.

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

Вдруг он наткнулся на что-то большое и с шипами. Это был хвост дракона.

Хвост шелохнулся, а вместе с ним и дракон.

Приглядевшись, Эйнар обнаружил, что он ранен.

– Как тебя зовут?
– Сидра, а тебя?
– Эйнар. Не бойся, я помогу тебе.

Викинг нарвал охапку листьев лечебного растения и сделал из них средство для заживления ран. Рецепт он вычитал в одной из книжек.

Дракону сразу полегчало.

– Так ты не будешь меня убивать?
– Нет, я не такой. А ты?
– Вам, викингам, нельзя доверять. Но ты мне помог, поэтому нет. Но тебе же нельзя будет вернуться в племя?
– Да, я знаю.
– И куда пойдешь?
– Еще не решил.
– Оставайся в пустоши – я тебя всему научу и со всем помогу.

Так Эйнар и остался жить в Драконьей пустоши.

 

***

Вскоре дракон и викинг стали лучшими друзьями.

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

Днем они вместе охотились, а по вечерам – жарили мясо и весело болтали, пели песни и развлекались.

***

Как-то во время охоты драконы попросили Эйнара подождать у одного из валунов и, перешептываясь, пошли в обход леса. При этом вид у них был очень озадаченный и слегка напуганный.

Эйнар на цыпочках проследовал за ними и подслушал их разговоры.

И тут ему открылась страшная тайна. Оказывается, большую часть добычи драконы относили в логово гигантского черного дракона Ужасного, который по размеру значительно превосходил их всех и мог их спокойно съесть.

Ужасный не любил викингов, поэтому и приказывал драконами воровать их девушек, еду и скот.

***
– Дракон Ужасный – причина вражды между драконами и викингами? Как вы могли от меня скрыть такое?
– Эйнар, у нас не было выбора – иначе он бы тебя съел, а мы этого не хотели.
– Но, получается, драконы и викинги могут жить в мире! Главное – одолеть Ужасного!
– Но это невозможно…
– Возможно! Я пойду в свою деревню и приведу подкрепление. Уверен, вместе мы победим!

Черный гигантский дракон Ужасный – новая неучтенная ранее сущность, новая информация, которая могла в корне поменять всю предметную область, а с ней – и бизнес-модель. Иначе говоря – ошибка в проектировании.

 

***
Эйнар пришел в родное племя. Ему никто не был рад.

Весь путь до дома отца его сопровождали неодобрительные возгласы и улюлюканья.

«Зачем вернулся, трус! Тебе здесь не место!», – то и дело раздавалось с разных сторон.

Наконец, он дошел до хижины вождя.

– Зачем ты здесь, сын мой? Тебя не должно здесь быть, ты не прошел испытание, уходи.
– Но отец, выслушай меня! Драконы и люди не должны враждовать! Мы не должны убивать их!
– С чего ты взял?
– Главная причина – гигантский черный дракон Ужасный, который живет в пещере, недалеко от пустоши за лесом. Он ненавидит викингов и хочет всех нас уничтожить! А другие драконы хорошие и миролюбивые, они не желают нам зла, а делают его против воли. Я со всеми ними подружился.
– Гигантский черный дракон – причина наших бед? Что ж, тогда мы его уничтожим. Но обряд инициации не будем отменять – таковы священные традиции.
– Но отец…
– Молчи. А тебя закуем в кандалы и посадим в темницу, чтоб не мешал операции.
– Но так нельзя…
– Молчи. Атакуем завтра!

***
Наступил день битвы. Сгустились темные тучи.

Викинги, вооружившись копьями и вилами, отправились в логово черного дракона.

Начался бой. Но силы были слишком неравны: викинги не могли справиться с гигантским драконом и готовились принять верную смерть в последнем бою.

«Вам меня не победить», – взревел Ужасный, выдохнув столп пламени.

Казалось, исход был предрешен.

Но вдруг неожиданно в небесах появился Эйнар со стаей драконов, верхом на одном из них. Его друг, дракон Сидра, спалил темницу и освободил его от кандалов.

Так драконы и люди объединились в битве века и вместе повергли общего врага –гигантского дракона.

В этой истории произошло несколько Domain Events – событий, повлиявших на ее ход. Это своеобразный аналог важных действий и фактов в бизнесе, которые происходят как следствие другого отдельного действия и становятся логикой предметной области.

Этими событиями стали: обряд инициации, встреча Эйнара с драконом, раскрытие тайны о гигантском драконе и финальная битва.

 

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

Так Эйнар получил любовь и уважение в своем племени, много друзей, и стал помощником вождя, обряд инициации был отменен, а между драконами и викингами воцарилась мир.

Мораль

Финальная битва завершила процесс. А может, только начала – со сменой бизнес-модели взаимодействия с драконами, и викингам, и драконам нужно будет многое изменить в своем укладе. Грядет крупная оптимизация, так сказать. Племя (компания) на пороге важных перемен. Но это уже совсем другая история.