Разработка Веб-приложения

  • Вид работы:
    Дипломная (ВКР)
  • Предмет:
    Информационное обеспечение, программирование
  • Язык:
    Русский
    ,
    Формат файла:
    MS Word
    505,14 Кб
  • Опубликовано:
    2017-08-11
Вы можете узнать стоимость помощи в написании студенческой работы.
Помощь в написании работы, которую точно примут!

Разработка Веб-приложения

Введение

инструмент архитектура laravel таблица

Актуальность исследования

В течение последних десяти лет на рынке интернет-приложений наблюдался значительный рост среди так называемых приложений-посредников. Такие приложения сильно облегчают коммуникацию между продавцами и покупателями. К таким приложениям относятся как классические онлайн биржи для продажи и покупки товаров общего пользования: eBay, Craigslist; так и менее традиционные: Airbnb, Aviasales. Особенно заметна тенденция к «уберизации» многих традиционных сервисов: то есть перехода от модели традиционных объявлений к более чистой версии биржи, где большую часть тяжелой работы по связыванию покупателя и продавца берет на себя сам сервис. В качестве примера можно привести отечественные remontnik.ru и repetitor.ru. На этих сайтах продавцам, в данных случаях ремонтникам и репетиторам, не требуется единолично просматривать всех потенциальных покупателей. Веб-сервис автоматически рекомендует наиболее подходящих потенциальных клиентов с учетом ключевых характеристик: местоположения обоих агентов и соответствие требований покупателя и навыков продавца.

Российский рынок IT по исторически сложившимся обстоятельствам всегда развивался обособленно от традиционных IT гигантов: Google, Facebook и Amazon. Их функционал в той или иной степени практически заменяют Yandex, Vk и Ozon соответственно. Не чужды Российскому веб-маркету и интернет-биржи: Avito и недавно появившаяся Ula. Тем не менее до этого момента в Российском сегменте не был представлен веб-сайт для перепродажи электронных билетов. Единственная международная компания, которая занимает собой достаточный сегмент рынка, чтобы рассматривать расширение в СНГ, Viagogo до сих пор ничего не предприняла предположительно из-за проблем с локализацией и с юридическими нюансами, несмотря на то, что в 2014 году Timepad оценил Российский рынок электронных билетов в 4.1 миллиард долларов (Timepad, 2014).

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

Все это обуславливает выбор в пользу разработки именно веб-приложения.

Практическое применение

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

Формализация

В целях дальнейшей формализации проекта были выделены и сформулированы следующие понятия.

Объект исследования: процесс разработки веб-приложений.

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

Цель исследования: разработать минимально жизнеспособный продукт по перепродаже электронных билетов с использованием современных методологий.

Задачи исследования:

Проанализировать существующие подходы к разработке сложных веб-сервисов и выбрать подходящий.

Выбрать необходимый инструментарий разработки.

Обосновать сделанный выбор

Определить конкретную логику бизнес-процессов.

Разработать минимально жизнеспособный продукт.

Структура работы

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

В Главе 2 будет уделено внимание описанию бизнес-процессов и логики системы. Эта глава ответит на следующие вопросы: на какие роли делятся пользователи, какие действия пользователи могут принимать, чем ограничены действия пользователей, как непосредственно должен будет происходить процесс взаимодействия пользователей друг с другом. То есть в этой главе будет описан процесс привлечения пользователей на сайт; сформулирован процесс загрузки билетов на сайт и процесс покупки; какие меры будут приниматься для предупреждения оппортунистического поведения. Также в этой главе мы коснемся состояние потенциального рынка электронных билетов в России; затронем то, как юридически сейчас регулируется распространение билетов на мероприятия в России. Не останется без внимания вопрос работы с клиентами: каких подходов следует придерживаться, а каких избегать. Техническая составляющая перечисленных в этой главе вопросов будет рассмотрена в Главе 1.

Ключевые термины- серверная часть веб-приложения.- часть веб-приложения, которая запускается на машине клиента.framework - полноценный продукт, на основе которого можно разрабатывать веб-приложение, следуемое принципам MVC.(model view controller) - методология разработки веб-приложений, согласно которой приложение разбивается на независимые части. Model описывает объектную форму бизнес-логики и является интерфейсом в базе-данных. View - генерирует отображения веб-страниц на основе предоставляемой ей модели. Controller - управляет веб-запросами и определяет, как на них отвечать.(Object-Relational Mapping) - программный объектно-ориентированный интерфейс к базе данных, который автоматически заменяет реляционные связи на объектные.API (application programming interface) - интерфейс, как правило, реализуемый с помощью HTTP запросов, который предоставляет доступ к данным веб-сервиса.

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

Глава 1

Основные принципы работы веб-сайта не претерпели сильных изменений за последние 20 лет. Клиент все так же отправляет HTTP запрос на сервер и сервер возвращает ему некоторый ответ. Это может быть HTML-страница или JSON-объект. Однако за время развития интернета этот простой функционал стал обрастать новыми дополнениями. JavaScript превращал статичные страницы в сложные интерфейсы и все это запускалось примерно-одинаково на всех машинах, где был установлен браузер, что в свое время было революционно. С появлением асинхронных ajax-запросов сложность интерфейсов возросла еще больше. Возрастающая сложность явилась причиной появления спроса на фронтенд-фреймворки, а забота о безопасности и желание использовать шаблонную разработку - бэкенд-фреймворки.

Одной из самых основных методологий веб-разработки является разделение фронтенд и бэкенд частей. Следуя ей, разработчики могут оставаться гибкими в выборе решений для разных задач. Доступ к базе данных и к бизнес-логике имеет только независимая бэкенд часть программы, а за вывод информации пользователю и получение ввода от пользователя отвечает фронтенд часть. В теории обе эти части должны быть свободно заменяемы. То есть разработчики могут полностью заменить стек фронтенд составляющей без необходимости менять что-либо в бэкенде. Такой подход в программировании называется loose coupling, то есть отказ от сильной взаимозависимости частей. С таким подходом один сервер может обслуживать несколько разных приложений: веб, мобильное приложение и десктопное.

Выбор инструментов

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

Перед разработкой приложения были сформулированы следующие требования к системе:

Масштабируемость. Возможность повышать пропускную способность сервиса и добавлять новый функционал без необходимости сильно менять существующий код.

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

Было решено вести разработку в IDE компании JetBrains. Их продукты отличаются большим функционалом и широкими возможностями для модификаций с помощью встроенной системы модулей. В PhpStorm, среде, где велась разработка, имелись встроенные инструменты для работы с модулями сборки, репозиториями и тестами, что значительно ускорило процесс разработки. В качестве репозитория была выбрана открытая платформа GitHub.

Перед тем, как выбрать бэкенд фреймворк приложения, необходимо определиться с языком программирования. Из все характеристик языка программирования нас интересует, является ли язык интерпретируемым или компилируемым. По определению, компилируемые языки программирования задачи выполняют быстрее, чем интерпретируемые, и есть много решений на базе компилируемо-интерпретируемых языков: Java и C#. Учитывая значительный опыт работы с языком C#, казалось, должно было быть принято решение использовать ASP.NET в качестве веб-фреймворка, но как раз компилируемость языка стала решающим фактором. Дело в том, что, не имея за плечами опыт разработки таких масштабных продуктов, хотелось иметь возможность быстро проектировать и тестировать небольшие части программы, но так как для того, чтобы изменения кода вступили в силу, приходится ждать значительное время до завершения компиляции проекта, пришлось отказаться от языков требующих предварительной компиляции.

С интерпретируемыми языками ситуация проще. Для того, чтобы протестировать изменения достаточно всего лишь обновить страницу в браузере, тем более, что этот процесс можно автоматизировать, подключив инструмент, который при изменении файлов разработки, сам обновляет страницу. Также опять из-за отсутствия опыта работы с бэкенд фреймоврками, необходим был продукт с низким порогом входа, доступной документацией и обучающим сообществом. Laravel framework включает в себя все эти характеристики, плюс удовлетворяет второму пункту из требований к системе - безопасности. Laravel имеет встроенные системы для работы с базами данных, аутентификацией, регистрацией и управлением ролями пользователей (Stauffer, 2016; Malatesta 2015).

Архитектура приложений Laravelопределяют как full-stack фреймворк, поскольку он может работать со всеми возможными частями веб-приложения. К таким частям можно отнести: веб-сервисы, управление базами данных, генерация HMTL, маршрутизация, кеширование, аутентификация, локализация, управление группами пользователей, сборка css и js файлов, инкапсуляция ресурсов и многое другое. Таким образом вертикально интегрированная среда веб-разработки обеспечивает лучший опыт для разработчика. С Laravel разработчик может взаимодействовать как через встроенную утилиту командной строки, которая управляет средой проекта Laravel, так и просто с помощью настройки конфигурационных файлов вручную. Как правило оба этих способа используются вместе.

Одна из интересных особенностей Laravel заключается в том, что она накладывает некоторые довольно серьезные ограничения на структуру веб-приложений. Но, как ни странно, эти ограничения упрощают процесс разработки. Laravel отличается от других вертикально интегрированных сред тем, что она конфигурациям предпочитает конвенции. В то время как в некоторых веб-фреймворках, написанных на Java, Python или PHP, часто требуется редактирование очень большого объема файлов с конфигурациями, то для начала работы с Laravel никаких настроек практически не требуется, разве что кроме нескольких строк на PHP. Стоит отметить, что большое количество конфигурационных файлов в Laravel написано на PHP. Такой подход в избегании файлов конфигурации позволяет приложениям, написанным под разные нужды, поддерживать узнаваемую структуру кода.

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

Рисунок 1. Файловая структура

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

/app/

Состоит из контроллеров MVC модели, моделей ORM и утилит консоли.

/bootstrap/

Содержит в себе файлы, которые необходимы для запуска и работы ядра Laravel.

/config/

Только по названию можно определить, что в этой папке хранятся файлы для настройки всевозможных модулей Laravel: начиная с базы данных и кеширования, заканчивая модулем отправки писем и файловой системой.

/database/

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

/node_modules/

Папка, в которой хранятся подключаемые JS модули, установленные с помощью утилиты nvm.

/public/

Только эта папка на сервере доступна внешнему миру. На этот каталог должен ссылаться веб-сервер. Он содержит загрузочный файл index.php, который запускает ядро Laravel. Этот каталог также может быть использован для хранения любых общедоступных статических файлов, таких как CSS, JavaScript, изображения и другие.

/python/

Папка, созданная для хранения в ней python-утилит, предназначенных для работы с API Kudago.

/resources/

В этой папке находятся ресурсы для работы с фронтендом: исходные JavaScript и css файлы для сборок, файлы локализации и файлы представлений.

/routes/

Здесь хранятся файлы для конфигурации модуля маршрутизации, а именно web.php, работа которого будет подробно описана.

/storage/

Эта папка предназначена для хранения генерируемых работой Laravel файлов: сессий, кеша и логов.

/tests/

Как следует из названия, в этой папке хранятся файлы модульных тестов.

/vendor/

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

.env

Из этого файла Laravel берет environment-переменные, например, здесь, с помощью изменения значения переменной DEBUG, можно задать состояние Laravel приложения - production или debug.

gulpfile.js

Файл настройки модуля автоматизации задач сборки Gulp.

В этом файле находится конфигурация виртуальной машины для разработки для Vagrant.



Model-View-Controller, как и подавляющее большинство вертикально интегрированных фреймворков следует архитектурному паттерну MVC (Model-View-Controller), или Модель-Представление-Контроллер по-русски, который обеспечивает разделений бизнес-логики от логики представления, связанной с графическим пользовательским интерфейсом (GUI - graphical user interface). В случае с веб-приложениями Laravel бизнес-логика обычно состоит из моделей данных для таких вещей, как пользователи, сообщения в блогах, а GUI, это просто веб-страница в веб-браузере. Шаблон проектирования MVC очень популярен в пространстве веб-разработки.

В шаблоне MVC существует три компонента:

Модель - каскад, вокруг которого работает приложение. Модели основаны на реальных предметах, таких как человек, событие, билет или продукт. Самый простой пример модели: запись в блоге. Модели как правило являются постоянными и хранятся вне приложения, часто в базе данных. Модель - это больше, чем просто данные; Она применяет все бизнес-правила, применимые к этим данным. Например, если скидка не должна применяться к билету на сумму менее 100 рублей, модель будет применять ограничение. Это имеет смысл; Поставив реализацию этих бизнес-правил в модель, мы убеждаемся, что ничто иное в приложении не может сделать наши данные недействительными. Модель - это последний рубеж для защиты и представления данных.

Представление - визуальное представление модели с учетом какого-либо контекста. Обычно это результирующая разметка, которую фреймворк передает браузеру, например, HTML страница, представляющая собой отображение информации о билете в браузере. Уровень представления отвечает за создание пользовательского интерфейса, обычно на основе данных в модели. Например, в интернет-магазине будет список продуктов, которые будут отображаться на экране каталога. Этот список будет доступен через модель, но это будет представление, которое обращается к списку из модели и форматирует его для конечного пользователя. Хотя представление может предоставлять пользователю различные способы ввода данных, само представление никогда не обрабатывает поступающие данные. Работа представления закончена после отображения данных. Однако, стоит заметить, что это правило в паттерне MVC нарушается чаще всего. Как правило, представление еще участвует в валидации вводимых данных, просто потому что, валидация на машине клиента будет происходить быстрее.

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

Типичное Laravel приложение состоит из вышеперечисленных компонентов MVC как указано ниже.

Рисунок 2. MVC

При взаимодействии с приложением Laravel браузер отправляет запрос, который принимается веб-сервером и передается в механизм маршрутизации Laravel. Маршрутизатор (Router) Laravel получает запрос и перенаправляет его на соответствующий метод класса контроллера, основанный на шаблоне URL маршрутизации.

Затем управляет передается в класс контроллера. В некоторых случаях контроллер немедленно выдает представление, которое является шаблоном, который преобразуется в HTML и отправляется обратно в браузер. Чаще всего для динамических сайтов контроллер взаимодействует с моделью, которая представляет собой объект PHP, который в свою очередь представляет элемент приложения (например, пользователя, мероприятие) и отвечает за связь с базой данных. После вызова модели контроллер затем отображает окончательный вид (HTML, CSS и изображения) и возвращает полную веб-страницу в браузер пользователя.продвигает идею о том, что модели, представления и контроллеры должны быть отделены друг от друга, сохраняя код для каждого из этих элементов в виде отдельных файлов в отдельных каталогах. Здесь вступает в действие структура каталогов Laravel. Шаблоны проектирования, такие как MVC, создаются для облегчения жизни разработчика. В этой области Laravel в разы обходит чистый PHP-код, который не следует какой-либо парадигме, и таким образом оправдывает свое существование.

Модель использованной базы данных

В качестве базы данных была выбрана реализация SQL от Oracle: MySQL. За последнее время в моду вошли нереляционные базы данных, такие как MongoDB и NoSQL. Следует отметить, что нереляционные базы данных очень хорошо применимы к узкому спектру задач, но значительно уступают реляционным, если речь заходит о «классических» базах данных. Такая база разрабатывается без знаний обо всех возможных применениях в программе. Правила нормализации как раз призваны подготовить базу данных к любым запросам от пользователя с наименьшими затратами по времени и памяти.

Отдельно хочется упомянуть разработанную систему для заполнения базы данных информацией о предстоящий событиях. Ручное заполнение информации о каждом мероприятия оказывается неэффективным. Поэтому было принято решение разработать скрипт, который бы автоматически загружал данные из открытого доступа. KudaGo - это веб-сайт, который предоставляет информацию обо всех предстоящих событиях. Предоставленное на данном веб-сайте API распространяется в свободном доступе, что облегчает разработку скрипта, который бы каждый день автоматически загружал в базу данных информацию о мероприятиях из KudaGo. Соответственно, была разработана база данных, диаграмма которой представлена на Рисунке 1. Стоит отметить встроенный в Laravel инструментарий для работы с базами данных с помощью миграций. Это ставит плюс в копилку Laravel за счет выполнения первого требования к продукту: масштабируемости. На Рисунке 2 можно увидеть пример строк из таблицы events.

Стоит отметить, что эта схема не представляет собой отображение конечной версии базы данных. Данная версия базы данных разработана непосредственно для хранения информации о мероприятиях, загруженных с использованием API Kudago.

Ниже представлены скриншоты из MySQL Workbench Tool - графического интерфейса для управления баз данных.

Рисунок 3. Схема базы данных

Рисунок 4. Вывод записей из таблицы с событиями

Заполнение базы данных

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

Вводимую информацию нужно модерировать вручную.

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

Сайт Kudago представляет из себя агрегатор событий из следующих городов России и ближнего зарубежья: Москва, Санкт-Петербург, Екатеринбург, Новосибирск, Казань, Краснодар, Красноярск, Нижний-Новгород, Сама, Сочи, Уфа, Выборг и Киев. Каждое событие сопровождается описанием и фотографиями. API Kudago - это база событий и мест, распространяемая с открытой лицензией.

В базе данных, предоставляемой Kudago, имеются следующие объекты:

Категории объектов

Города

События

Категории событий

Новости

Подборки

Места

Фильмы

Показы

Агенты

Роли

В разрабатываемом приложении требуются только Города, Места, События и Категории событий.не предоставляет библиотеки для работы с API, поэтому необходимо было разработать функции для работы с REST-запросами Kudago. Рассмотрим необходимые REST-запросы и параметры, которые они могут принимать.

Для получения Событий предоставляется запрос:

/public-api/{version}/events/{?lang,fields,expand,order_by,text_format,ids,location,actual_since,actual_until,is_free,categories,lon,lat,radius}

Опишем параметры, которые принимает этот запрос.

Имя

По умолчанию

Описание

version

обяз.

версия API Варианты: v1 v1.1 v1.2 v1.3

lang

ru

язык ответа Варианты: ru en

page

1

выдать указанную страницу пагинатора

page_size

20

число отдаваемых объектов на странице. Максимальное значение - 100

fields

id, title, slug

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

expand

необ.

включить в выдачу более подробную информацию для указанных полей, можно несколько через запятую Варианты: images place location dates participants

order_by

необ.

сортировать выдачу по указанным полям, можно несколько через запятую; если поле указано со знаком минус, то происходит сортировка по убыванию Варианты: id publication_date title slug place description body_textlocation tagline age_restriction price is_free favorites_countcomments_count short_title

text_format

html

html - текст с тэгами text - текст без тегов, от ссылок остается только название

ids

необ.

location

необ.

включить в выдачу события только из указанного города (каждому городу соответствует укрощенное название на латинице - слаг

actual_since

необ.

включить в выдачу только те события, которые начались после указанного момента времени (в формате UNIX timestamp или ISO 8601, в любом случае время считается в UTC)

actual_until

необ.

включить в выдачу только те события, которые закончились до указанного момента времени (в формате UNIX timestamp или ISO 8601, в любом случае время считается в UTC)

place_id

необ.

включить в выдачу события только для указанного места

parent_id

необ.

включить в выдачу события, дочерние к указанному событию

is_free

необ.

включить в выдачу только бесплатные события Варианты: 1 0 true false

categories

необ.

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

tags

необ.

включить выдачу только события с указанными слагами тэгов, можно несколько через запятую; если тэг указан со знаком минус, то события с таким тэгом будут выключены из выдачи

lon, lat, radius

необ.

lat, lon и radius вместе фильтруют события вокруг указанных координат; радиус указывается в метрах


Список полей, которые можно запросить через атрибут fields.- идентификатор_date - дата публикации- даты проведения- название_title - короткое название- слаг- место проведения- описание_text - полное описание- город проведения- список категорий- тэглайн_restriction - возрастное ограничение- стоимость_free - бесплатное ли событие- картинки_count - количество добавлений в «избранное»_count - число комментариев к событию_url - адрес события на сайте kudago.com- тэги события- агенты события

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

Разработанный на Python скрипт запускается раз в сутки и обновляет информацию в базе данных, осуществляя запросы в API Kudago.

Поисковая часть приложения

Так как приложение представляет из себя в каком-то роде агрегатор документов, то есть билетов, то в нем должна присутствовать система для быстрого осуществления поиска по всей базе данных. Эта система должна быть быстрой, масштабируемой и обладать функцией автодополнения запросов. Все эти требования выполняет Elasticsearch- это открыто распространяемый поисковый движок. Документы в этой системе хранятся в формате JSON. Продукт разработан на основе фреймворка для создания распределенных программ Java Hadoop. В Laravel встроен модуль для подключения поисковых движков, в том числе и Elasticsearch.

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

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

Оно позволяет горизонтально масштабировать объем хранимой информации

Оно позволяет распределять и паралеллизировать операции среди осколков (и потенциально между несколькими узлами), повышая таким образом производительность

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

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

Эта система важна по следующим причинам:

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

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

Итак, каждый индекс можно разбить на несколько осколков. У индекса может быть создана одна и несколько резервных копий (реплик). Число осколков и реплик может быть определено для каждого индекса во создания ин время создания индекса. После создания индекса можно изменять количество реплик, но количество осколков индекса после создания изменить невозможно. По умолчанию, индекс создается с 5 осколками.

Ниже представлен результат выполнения следующего HTTP запроса:/_cat/health?v

Рисунок 5. Состояние кластера Elasticsearch

Этот запрос выводит состояние кластера. Стоит отметить, что статус на момент выполнения запроса, выводится как желтый, потому что не все осколки были распределены по узлам. Это объясняется тем, что в кластере сейчас только один узел.

Консольные команды Laravel

Вместе с Laravel поставляется консольный инструмент для работы с фреймворком под названием Artisan. В него входят модули для генерации всевозможных файлов в фреймворке, программа для консольной работы со встроенной ORM, которая называется Tinker и многие другие. Также очень важным преимуществом этого инструмента является возможность создавать кастомные команды. Эта возможность была использована для создания команды es:fill. Эта команда заполняет и обновляет индекс поискового движка Elasticsearch. Необходимость в переносе этой задачи в отдельную команду обусловливается тем, что эта команда должна вызваться каждый раз, когда обновляется информация о событиях в базе данных, или как минимум раз в сутки. Вынеся подпрограмму, которая обновляет индекс поискового движка, мы упрощаем последующую автоматизацию этого процесса.

Миграции

Часто в ходе разработки и во время жизненного цикла приложения к нему могут добавляться новые требования и функционал. С изменением запросов к приложению, могут меняться требования к структуре базы данных. Структуру базы данных можно редактировать вручную «на ходу», но это может быть чревато последствиями. Одна ошибка, допущенная по невнимательности, может стоить десятки часов и сотни упущенных пользователей. Очевидно, необходим инструмент, интерфейс, который бы давал доступ к системе базы-данных, связанный с моделью приложения. Такой инструмент называется миграции. Миграция представляет из себя по сути контроль версий для базы данных. Встроенные системы миграций есть у всех больших реализаций SQL: Oracle, MySQL, MSSQL и т.д. Laravel предоставляет «из коробки» интерфейс для работы с миграциями всех движков баз-данных. Таким образом поддерживается подход loose coupling: миграции связаны с логический моделью приложения и есть возможность менять движки баз-данных, без потери этих миграций. Миграции создаются с помощью встроенного в Laravel консольного интерфейса, под названием Artisan, а именно с помощью команды php artisan make:migration, после которой с помощью аргументов можно задать параметры. Например -create=$name создает файл миграции для создания таблицы, где $name это желаемое имя таблицы. Как уже было сказано, это команда создает php файл, в котором задаются атрибуты таблицы: типы столбцов, правила, внешние связи. В этом файле задаются команды, которые будут выполнены при вызове команды migration:rollback, то есть «отката» к старой версии. Также стоит отметить, что при генерации файла, в конце названия приписывается timestamp, время создания. На это время и ориентируется программа, при вызове миграции, для сохранения последовательности миграций.

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

Здесь необходимо отметить, что сейчас понятие Frontend можно интерпретировать по-разному. Фронтендом могут называть только то, что выполняется на машине клиента. В этой работе в фронтенд часть приложения входят все модули, которые так или иначе непосредственно генерируют и влияют на работу интерфейса приложения, то есть на то, как себя ведет HTML страница. К этим модулям относятся встроенный в Laravel шаблонизатор, JavaScript и CSS библиотеки.

Шаблонизатор

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

Было бы проще и правильней с точки зрения архитектуры, вынести повторяющиеся блоки в отдельные файлы или классы. К сожалению, HTML разметка по определению не может предоставить такой функционал. Инструмент, который позволяет использовать модули, или шаблоны, при разработке веб-страниц, называется шаблонизатор. Laravel поставляется с предустановленным шаблонизатором, носящим название Blade. Файлы, которые используют Blade, имеют расширение .blade.php и как правило хранятся в папке resources/views.

Страницы в Blade генерируются по принципу наследования. То есть, имеется страница-родитель с именованными секциями, например, с секцией ‘content’. С помощью так называемых директив можно задавать куски кода, которые будут использованы как модули. Например, директива @extends(‘layouts.master) указывает, какой макет страница должна унаследовать. В этом родительском макете будет расписан header, навигационная панель и footer.

На скриншоте ниже представлен пример файла с представлением страницы входа в систему.

Рисунок 6. login.blade.php

Blade реализует на своей основе также инструмент шаблонизации, под названием Mustache, что переводится как «усы». Такое странное на первый взгляд название можно объяснить тем, что этот язык «разметки» использует в качестве управляющего символа символы ‘{‘ и ‘}’, которые могут быть использованы при написании эмотикона с усами.

Валидация форм

Валидация форм является самой старой и тривиальной задачей, для решения которой и использовался изначально встроенный в браузер JavaScript. Естественно, что для решения этой задачи существует множество решений и библиотек. Мое внимание остановилось на плагине к библиотеке jQuery, самой распространенной библиотеке JavaScript, под названием jQuery Validation. Это очень удобный инструмент по следующим причинам:

Гибкая система

Простая система добавления кастомных правил

Встроенная система локализацииSteps для так называемых wizard форм. Это формы несколькими шагами. Такая используется, например, на странице загрузки билета. Также эту библиотеку можно использовать для генерации меню со вкладками, в частности на странице с личным кабинетом. Ниже представлен скриншот страницы личного кабинета, где использовалась библиотека jQuery Steps для создания интерфейса со вкладками.

Рисунок 7. Личный кабинет

Каскадные таблицы стилей

Современные дизайн стандарты очень требовательны к разработчикам. Для того, чтобы добиться от обычных стандартов CSS и HTML поведения, которое ожидает пользователь, нужно досконально разбираться во всех нюансах реализаций этих технологий на каждом браузере. К счастью, для тех, кто не может позволить себе выделять столько ресурсов, сколько требуют современные методологии разработки пользовательских интерфейсов, существуют так называемые CSS библиотеки, фреймворки и препроцессоры. Препроцессоры, такие как SASS и LESS, это надстройки над CSS, которые добавляют функционал из языков программирования: модульность и переменные. Браузеры не реализуют в себе интерпретаторы этих препроцессоров, именно поэтому они так и называются, и для того, чтобы разрабатываемый код выполнялся на машине клиента, код препроцессоров нужно компилировать в чистый CSS. С этой задачей отлично справляются таск-менеджеры, такие как Grunt и Gulp. В качестве CSS фреймворка был выбран самый популярный вариант - Bootstrap.

Структура сайта

Главная страница

Регистрации

Вывода информации о мероприятиях

Логина

Личный кабинет

Загрузка билета

Вывод информации о билете

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

Рисунок 8. Макет главной страницы

Процесс разработки

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

Среда разработки

Во времена становления интернета исходный код многих веб-приложений зачастую редактировался в обычном текстовом редакторе. Сейчас, когда каждый аспект веб-разработки оброс десятками подходов, расширений и инструментов это трудно представить. Сейчас проекты принято разрабатывать в так называемых средах разработки. Среды разработки чаще поставлялись вместе с компилируемыми языками, но за последние два десятилетия все интерпретируемые языки обзавелись своими средами разработки. В качестве основной среды разработки был выбрана программа PhpStorm от JetBrains. Это полноценная среда для работы с файлами всех расширений, которые могут быть задействованы в веб-разработке, включая PHP. К поддерживаемым расширениям также относятся: .js, .html, .css, .yaml, .json, .xml, .md, а также всевозможные вариации .js и .css файлов: препроцессоры и расширения, компилируемые в чистый JavaScript.

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

Таск-менеджер

В ходе разработки часто нужно выполнять типовые задачи. Такие как минификация, сборка и тестирование. Поэтому программы, позволяющие автоматизировать эти задачи, справедливо считаются очень полезными и используются повсеместно. Такие программы носят название таск-менеджеров. В ходе разработки был выбран таск-менеджер Gulp. Это свободно распространяемое ответвление проекта Grunt, другого таск-менеджера. Работа может осуществляться как через командную строку, так и через встроенный модуль в PhpStorm. от своего аналога, Grunt, отличается тем, что в Gulp код задач записывается на JavaScript коде, а не в конфигурационном файле.

Виртуальная машинапредоставляет удобный способ настройки и управления виртуальными машинами. Vagrant может работать с так называемыми коробками (boxes). Это заранее упакованные и сконфигурированные образы виртуальных машин. Прямо на сайте Vagrant можно выбрать среди списка загруженных коробок подходящую себе. (Mitchell Hashimoto, 2013)Homestead это официальная, предварительно упакованная коробка Vagrant, которая предоставляет среду разработки без необходимости установки PHP, настройки веб-сервера и любого другого программного обеспечения на локальную машину. Если что-то пойдет не так, коробку можно быстро снести и поставить новую. Это значительно упрощает процесс разработки.

Виртуальная машина использовалась только во время разработки. Сервер, на котором развернуто приложение, был настроен самостоятельно.

Развертывание

Как сказано выше, было принято решение хранить проект на репозитории GitHub. Это заметно упростило процесс развертывания на сервере, так как процесс копирования проекта на сервер укладывалось в несколько консольных команд.

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

Сервер представляет из себя выделенную виртуальную машину с операционной системой Ubuntu 10.04. Для работы Laravel приложения достаточно было поменять несколько глобальных переменных и конфигурационных настроек. Перед запуском приложения был настроен Apache сервер, который ссылается на папку /public в приложении.

Работа с серверов производится посредством протокола SSH.

Глава 2. Постановка решаемых задач

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

Попытаться продать билет друзьям.

Попытаться продать билет лично через социальные сети.

Перед началом лично приехать на место, где будет проводиться мероприятие, и попытаться продать билет там.

Человек, который хочет купить билет «с рук», рискует быть обманутым мошенником. Такого рода сделку необходимо гарантировать третьей стороной.

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

При проработке бизнес-модели любого подобного проекта, следует решить следующие вопросы:

Как предупредить оппортунистическое поведение пользователей?

Как набрать критическую массу пользователей и поддержать соотношение спроса и предложения?

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

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

Маркетинг

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

Продавцы

Покупатели

Официальные распространители

Продавец - это любой, кто хочет продать свой билет. Это может быть профессиональный скупщик билетов или же обычный человек. Подход к привлечению этих пользователей от этого не будет меняться. Так как подобного сервиса в русскоязычном сегменте не существует, продвижение через контекстную рекламу будет не рентабельно. Контекстная реклама подразумевает то, что целевая аудитория знает, чего хочет, ведь для того, чтобы сделать поисковый запрос, его нужно сформулировать. Таргетированная реклама, напротив, должна работать намного эффективней. Фильтровать целевую аудиторию в социальных сетях можно будет по состоянию в группе мероприятия или по комментариям, содержащим вариации фразы «продам билет». Сейчас довольно популярно использовать в качестве площадки по продаже билетов тематические форумы. По этому признаку также можно будет искать целевую аудиторию для группы продавцов.

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

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

Юридический аспект

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

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

Бизнес-модель

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

Покупатели

Продавцы

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

Рисунок 9. Бизнес-модель

Рисунок 10. Бизнес-модель

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

Выставление билета на продажу

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

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

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

Ниже представлены скриншоты страниц, связанных с выставлением билета на продажу.

Рисунок 11. Выбор события

Рисунок 12. Ввод информации о билете

Покупка билета

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

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

После отправки поискового запроса, пользователю будет выведен результат. Мероприятие будет выводиться только тогда, когда на это мероприятие был выставлен один или несколько билетов.

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

Каждая сторона сможет узнать о состоянии всех своих споров через личный кабинет. Информация об изменении состояния споров будет передаваться пользователю через email-рассылку.

В перспективе будет уместно разработать веб-интерфейс для модераторов веб-сайта. В этой панели управления модератор сможет вести споры удобным через удобный интерфейс и просматривать загруженные билеты.

Монетизация

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

Заключение

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

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

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

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

Литература

1.      Bean, Martin (2015). Laravel 5 Essentials

2.      Cassio de Sousa Antonio (2015). Pro React. Apress.

3.      Flanagan, David (2011). JavaScript: The Definitive Guide (6th ed.). O'Reilly & Associates.

4.      Goodman, Danny; Eich, Brendan (2001). JavaScript Bible. John Wiley & Sons.

.        Laravel Documentation (version 5.4)

6.      Malatesta, Frank. (2015). Learning Laravel's Eloquent. Packt Publishing.

7.      Maynard, Travis (2015). Getting Started with Gulp. Packt Publishing Ltd.

8.      McFarland, David (2014). JavaScript & jQuery: The Missing Manual (3rd ed.) O'Reilly Media

9.      Mitchell Hashimoto (2013). Vagrant: Up and Running (PDF). O'Reilly Media.

.        Sheldon, Robert; Moye, Jeoffrey (2007) MySQL 5: базовый курс «Диалектика»

11.    Stauffer, Max. (2016). Laravel: Up and Running. O'Reilly Media.

12.    TimePad (2014). The market of electronic tickets for events in Russia

13.    Кузнецов Максим, Симдянов Игорь. (2006) Самоучитель MySQL 5. «БХВ-Петербург»

.        Джейсон Ленгсторф (2010). PHP и jQuery для профессионалов. «Вильямс»

.        Стив Суэринг, Тим Конверс, Джойс Парк. (2010). PHP и MySQL = PHP 6 and MySQL 6 Bible. «Диалектика»

.        Кузнецов Максим, Симдянов Игорь. (2007). Объектно-ориентированное программирование на PHP. СПб.: «БХВ-Петербург»

.        Кристиан Дари, Эмилиан Баланеску.(2010). PHP и MySQL: создание интернет-магазина «Вильямс»

18.    Lockhart, J. (2015). Modern PHP New Features and Good Practices. O'Reilly Media

19.    Dow, J. (2015). Learning Application Deployment with Laravel Packt Publishing

.        Christopher John Pecoraro (2015). Mastering Laravel Packt Publishing

.        Arda Kilicdagi, H. Ibrahim YILMAZ. (2014). Laravel Design Patterns and Best Practices Packt Publishing

.        Matula, T. (2013). Laravel Application Development Cookbook. Packt Publishing

.        Copeland, R. (2008) Essential SQLAlchemy. O'Reilly

24.    Lutz, Mark. (2013). Learning Python (5th ed.). O'Reilly Media

25.    Summerfield, Mark (2009). Programming in Python 3 (2nd ed.). Addison-Wesley Professional.

.        Артем А. (2015). Сенаторов. Битва за подписчика «ВКонтакте»: SMM-руководство. Альпина Паблишер

.        Севостьянов, И. (2010). Поисковая оптимизация. Практическое руководство по продвижению сайта в Интернете. «Питер»

.        Юрасов А.В. (2008). Основы электронной коммерции. Горячая линия Телеком

.        Нейл Ботвик. (2015). Ubuntu - 10!. Linux Format.

30.    Grant, Rickford; Bull, Phil (2010). Ubuntu for Non-Geeks: A Pain-Free, Get-Things-Done Guide (4th ed.). No Starch Press.

31.    Hudson, Andrew; Hudson, Paul; Helmke, Matthew; Troy, Ryan (2009). Ubuntu Unleashed 2010 Edition: Covering 9.10 and 10.4 (5th ed.).

32.    Leff, Avraham; Rayfield, James T. (2001). Web-Application Development Using the Model/View/Controller Design Pattern. IEEE Enterprise Distributed Object Computing Conference.

.        Эд Титтел, Джефф Ноубл. (2011). HTML, XHTML и CSS для чайников, 7-е издание. «Диалектика»

.        Стивен Шафер.(2011). HTML, XHTML и CSS. Библия пользователя, 5-е издание. «Диалектика»,

.        Кристофер Шмитт. (2007). CSS. Рецепты программирования. БХВ-Петербург

Приложение

Ниже представлена ссылка на репозиторий с проектом:

github.com/artemmnad/tickethand

Похожие работы на - Разработка Веб-приложения

 

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