Please use this identifier to cite or link to this item:
https://er.chdtu.edu.ua/handle/ChSTU/9031| Title: | Проектування інформаційної системи каталогу напоїв |
| Authors: | Куницька, Світлана Юріївна Шраменко, Валерій Миколайович |
| Keywords: | КАТАЛОГ;МОБІЛЬНИЙ ДОДАТОК;НАПІЙ;КОКТЕЙЛЬ;РЕЦЕПТИ;CATALOG;MOBILE APPLICATION;DRINK;COCKTAIL;RECIPES |
| Issue Date: | 20-Jun-2024 |
| Abstract: | АНОТАЦІЯ
Розробник: Шраменко Валерій Миколайович
Назва кваліфікаційної роботи: «Проектування інформаційної системи каталогу напоїв»
Спеціальність: 121 «Інженерія програмного забезпечення»
Установа: Черкаський державний технологічний університет
Місто, рік: Черкаси, 2024 рік
Основні ідеї - створення мобільного додатку для перегляду покрокових рецептів приготування алкогольних та безалкогольних коктейлів.
Результати – архітектура та графічне подання мобільного додатку-каталогу рецептів напоїв.
Висновки – створений програмний комплекс мобільного додатку-каталогу рецептів алкогольних та безалкогольних напоїв. ABSTRACT Performer: Shramenko Valerii Title of the qualification work: Designing the information system of the beverage catalog Specialty: 121 "Software Engineering" Institution: Cherkasy State Technological University City, year: Cherkasy, 2024 Main ideas – Creating a mobile application for viewing step-by-step recipes for making alcoholic and non-alcoholic cocktails. Results - the architecture and graphic presentation of the mobile application catalog of drink recipes. Conclusions – a software complex of a mobile application catalog of recipes for alcoholic and non-alcoholic drinks has been created. |
| URI: | https://er.chdtu.edu.ua/handle/ChSTU/9031 |
| Appears in Collections: | 121 Інженерія програмного забезпечення (Інженерія програмного забезпечення) |
Files in This Item:
| File | Description | Size | Format | |
|---|---|---|---|---|
| Кваліфікаційна робота бакалавра Шраменко Валерій Миколайович.pdf Restricted Access | 2.31 MB | Adobe PDF | View/Open Request a copy |
Items in DSpace are protected by copyright, with all rights reserved, unless otherwise indicated.
Extracted text
МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
ЧЕРКАСЬКИЙ ДЕРЖАВНИЙ ТЕХНОЛОГІЧНИЙ УНІВЕРСИТЕТ
Факультет інформаційних технологій і систем
Кафедра програмного забезпечення автоматизованих систем
ПОЯСНЮВАЛЬНА ЗАПИСКА
до кваліфікаційної роботи
«бакалавра»
на тему: «Проектування інформаційної системи каталогу напоїв»
Виконав: студент 4 курсу, групи ПЗ-2004
Спеціальності
121 «Інженерія програмного забезпечення»
(шифр і назва напряму підготовки)
Студент Шраменко В.М.
(прізвище та ініціали)
Керівник Куницька С.Ю.
(прізвище та ініціали)
Рецензент Захарова М.В.
(прізвище та ініціали)
Черкаси 2024
Черкаський державний технологічний університет___________
Факультет інформаційних технологій і систем________________________________
Кафедра програмного забезпечення автоматизованих систем__________________
Освітній рівень бакалавр______________________________________________________
Спеціальність 121 «Інженерія програмного забезпечення»_________________________
Освітня програма Інженерія програмного забезпечення______________________________
ЗАТВЕРДЖУЮ
Зав. кафедри ПЗАС, д.т.н., професор
__________________ Сергій ГОЛУБ
«___» _______________ 2024 року
З А В Д А Н Н Я
НА КВАЛІФІКАЦІЙНУ РОБОТУ СТУДЕНТУ
Шраменку Валерію Миколайовичу________________________
(прізвище, ім’я, по батькові)
1. Тему проекту (роботи) Проектування інформаційної системи каталогу напоїв_________
Керівник проекту (роботи) Куницька Світлана Юріївна к.т.н., доцент___________________
Затверджені наказом Черкаського державного технологічного університету №60/04 від «26» лютого 2024
року
2. Строк подання студентом проекту (роботи) 12 червня 2024 року
3. Вхідні дані до проекту (роботи) стандарти програмного забезпечення; процеси управління; вимоги до
проекту; календарне планування проекту;
4. Зміст розрахунково-пояснювальної записки (перелік питань, які потрібно розробити)
Існуючі методи та засоби розв’язання поставлених задач_____________________________
Впровадження результатів досліджень у практику проектування програмного забезпечення
інформаційних систем__________________________________________________________
Розробка та тестування програмного забезпечення
Висновки
Додатки___________________________________
5. Перелік графічного матеріалу з точним зазначенням обов’язкових робіт проекту;
Слайд 1 – Титульний лист; Слайд 2 - Вступ; Слайд 3 – Первинні та детальні вимоги; Слайд 4 – Діаграма
прецендентів; Слайд 5 – Проектування логічної структури; Слайд 6 – Архітектурне проектування; Слайд
7 – Моделювання поведінки системи: Слайд 8 – Діаграма скінченного стану автомату; Слайд 9 –
Структурна та функціональна схема; Слайд 10 – Логічна схема; Слайд 11 – Cайт з посиланням на API;
Слайд 12 – Інтерфейс користувача; Слайд 13 – Тестування.
6. Консультанти розділів роботи
Прізвище, ініціали та посади Підпис, дата
Розділ
консультанта Завдання видав Завдання прийняв
1
2
3
7. Дата видачі завдання ____09 грудня 2023 року_______________
КАЛЕНДАРНИЙ ПЛАН
Строк
виконання
№
Назва етапів випускної роботи етапів Примітки
п/п
кваліфікаційної
роботи
1 Постановка задачі 05.12.2023 виконано
2 Підготовка завдання 13.12.2023 виконано
3 Погодження завдання 16.12.2023 виконано
4 Затвердження завдання 19.02.2024 виконано
Основна стадія
1 Аналіз конкуретів. 27.02.2024 виконано
2 Аналіз шляхів вирішення поставленої задачі 04.02.2024 виконано
3 Розрахунок основних параметрів роботи 10.03.2024 виконано
4 Вибір кінцевого варіанту проектного рішення 17.03.2024 виконано
5 Оформлення первісної редакції роботи 25.03.2024 виконано
Заключна стадія
1 Узгодження прийнятих проектних рішень з 31.04.2024 виконано
керівником
2 Оформлення пояснювальної записки роботи в 13.05.2024 виконано
кінцевій редакції
3 Попередній захист роботи 15.05.2024 виконано
4 Затвердження роботи 02.06.2024 виконано
5 Рецензування роботи 06.06.2024 виконано
6 Захист роботи 13.06.2024
Студент _____________________ Валерій ШРАМЕНКО
(підпис) (прізвище та ініціали)
Керівник роботи
к.т.н., доцент _____________________ Світлана КУНИЦЬКА
(підпис) (прізвище та ініціали)
АНОТАЦІЯ
Розробник: Шраменко Валерій Миколайович
Назва кваліфікаційної роботи: «Проектування інформаційної системи
каталогу напоїв»
Спеціальність: 121 «Інженерія програмного забезпечення»
Установа: Черкаський державний технологічний університет
Місто, рік: Черкаси, 2024 рік
Основні ідеї - створення мобільного додатку для перегляду покрокових
рецептів приготування алкогольних та безалкогольних коктейлів.
Результати – архітектура та графічне подання мобільного додатку-каталогу
рецептів напоїв.
Висновки – створений програмний комплекс мобільного додатку-каталогу
рецептів алкогольних та безалкогольних напоїв.
Ключові слова: КАТАЛОГ, МОБІЛЬНИЙ ДОДАТОК, НАПІЙ, КОКТЕЙЛЬ,
РЕЦЕПТИ.
ABSTRACT
Performer: Shramenko Valerii
Title of the qualification work: Designing the information system of the beverage
catalog
Specialty: 121 "Software Engineering"
Institution: Cherkasy State Technological University
City, year: Cherkasy, 2024
Main ideas – Creating a mobile application for viewing step-by-step recipes for
making alcoholic and non-alcoholic cocktails.
Results - the architecture and graphic presentation of the mobile application
catalog of drink recipes.
Conclusions – a software complex of a mobile application catalog of recipes for
alcoholic and non-alcoholic drinks has been created.
Keywords: CATALOG, MOBILE APPLICATION, DRINK, COCKTAIL,
RECIPES.
ЗМІСТ
ВСТУП .............................................................. Ошибка! Закладка не определена.
РОЗДІЛ 1 ІСНУЮЧУ МЕТОДИ ТА ЗАСОБИ РОЗВ’ЯЗАННЯ ПОСТАВЛЕНИХ
ЗАДАЧ .............................................................. Ошибка! Закладка не определена.
1.1 Опис предметної області……………………………………………………….6
1.2 Актуальність розробки додатку-каталогу напоїв……………………………..7
1.3 Огляд аналогів…………………………………………………………………..8
1.4 Напрямки розробки сучасних мобільних додатків………………………….10
1.5 Постановка задачі……………………………………………………………..10
РОЗДІЛ 2 ВПРОВАДЖЕННЯ РЕЗУЛЬТАТІВ ДОСЛІДЖЕНЬ У ПРАКТИКУ
ПРОЕКТУВАННЯ ПРОГРАМНОГО ЗАБЕЗПЕЧЕННЯ ІНФОРМАЦІЙНИХ
СИСТЕМ ................................................................................................................... 13
2.1 Моделювання предметної області ................................................................. 13
2.1.1 Предметна область моделювання. Модель предметної області. Словник
предметної області ........................................................................................... 13
2.1.2 Елементи моделювання предметної області .......................................... 14
2.1.3 Робоча область моделювання ................................................................. 14
2.2 Формування та аналіз вимог .......................................................................... 16
2.2.1 Формування вимог до програмного забезпечення. Первинні і детальні
вимоги. Вимоги замовника і розробника. Функціональні та нефункціональні
вимоги ............................................................................................................... 16
2.2.2 Формування вимог за допомогою діаграми прецедентів ...................... 17
2.3 Проектування логічної структури програмного комплексу ......................... 19
2.3.1 Діаграми класів ........................................................................................ 19
2.3.2 Діаграми пакетів ...................................................................................... 22
2.4 Архітектурне проектування ........................................................................... 23
2.4.1 Діаграма компонентів.............................................................................. 23
2.4.2 Розгортання програмної системи на апаратних засобах. Діаграма
розгортання ....................................................................................................... 24
Зм Лис № Докум. Підпис Дата ЧДТУ 242063.01 7ПЗ 3
Р озроб. Шраменко.В «Проектування інформаційної Літ. Лист Листів
Кер івник К уницька.С.
системи каталогу напоїв»
ФІТІС, Кафедра ПЗАС,
Н.контр. Півень О.Б.
З атв. Голуб С.В. (Пояснювальна записка)
ПЗ-2004
2.5 Моделювання поведінки системи.................................................................. 25
2.5.1 Діаграма діяльності ................................................................................. 25
2.5.2 Діаграма послідовності ........................................................................... 26
2.5.3 Діаграма комунікації ............................................................................... 27
2.5.4 Діаграма скінченного автомату .............................................................. 29
РОЗДІЛ 3 РОЗРОБКА ТА ТЕСТУВАННЯ ПРОГРАМНОГО ЗАБЕЗПЕЧЕННЯ 30
3.1 Розробка програмного комплексу ................................................................. 30
3.1.1 Обґрунтування вибору засобів реалізації .............Ошибка! Закладка не
определена.30
3.1.2 Опис структурної (функціональної) схеми ............................................ 31
3.1.3 Опис логічної схеми системи .................................................................. 32
3.1.4 Розробка бази даних ................................................................................ 33
3.1.5 Розробка інтерфейсу користувача .......................................................... 35
3.1.6 Опис розробки програмних компонентів ............................................... 37
3.2 Тестування системи ........................................................................................ 38
3.2.1 Модульне тестування .............................................................................. 38
3.2.2 Інтеграційне тестування .......................................................................... 39
3.2.3 Системне тестування ............................................................................... 40
3.2.4 Приймальне тестування .......................................................................... 41
3.3 Приклади впровадженого програмного комплексу ...................................... 42
ВИСНОВКИ ............................................................................................................. 45
СПИСОК ВИКОРИСТАНИХ ДЖЕРЕЛ ................................................................. 46
ДОДАТОК А ............................................................................................................ 49
ДОДАТОК Б ............................................................................................................. 51
ДОДАТОК Г ........................................................................................................... 101
Лист
ЧДТУ 242063.017ПЗ
З м. Лист № док. Підпис Дата
4
ЧДТУ 242063.017ПЗ
ВСТУП
Актуальність теми: у сучасному світі без цифрових технологій зовсім
нікуди. Люди прагнуть до спрощення життя, пристосовуються до швидкого ритму
життя, який з кожним роком стає все швидшим. Сфера обслуговування також
повинна пристосовуватись, адже не завжди виходить швидко знайти потрібний
рецепт приготування напою, через що і збільшується час очікування клієнта. Для
цього багато ресторанів починають використовувати різноманітне програмне
забезпечення, щоб прискорити роботу своїх співробітників. Одним з таких
варіантів є мобільний застосунок, який можна встановити як на телефон, так і на
планшет або інший пристрій, який використовує операційну систему Android.
Мета і завдання: розробити додаток, який надає можливість переглянути
рецепт напою для пришвидшення його приготування.
Для вирішення поставленої мети сформульовано наступні завдання:
Завдання 1. Виконати аналітичний огляд аналогів додатку.
Завдання 2. Розробити інтерфейсну частину користувача.
Завдання 3. Розробити серверну частину.
Завдання 4. Застосувати технології тестування програмного забезпечення.
Об’єкт розробки: розробка програмного забезпечення для пришвидшення
надання послуг у сфері харчування.
Предмет розробки: процес розробки мобільного додатку на ОС Android.
Методи проектування та конструювання: для досягнення поставленої
мети застосовано такі методи:
- аналіз аналогів додатків;
- проектування за допомоги UML діаграм;
- використання MVVM паттерну для розробки додатку;
- використання принципів ООП для розробки додатку.
Практичне значення отриманих результатів:
1 Під час проектування бази даних для полегшення розробки програмного
забезпечення було використано API – TheCocktailDB.
4
ЧДТУ 242063.017ПЗ
2 Був проведений аналіз додатків-аналогів для побудови власної
інтерфейсної частини програмного продукту з урахуванням побажань
майбутніх користувачів.
3 Спроектовано серверну частину.
4 Створено власний програмний продукт згідно методів розробки додатку,
описаних у ході проектування.
5
ЧДТУ 242063.017ПЗ
РОЗДІЛ 1 ІСНУЮЧІ МЕТОДИ ТА ЗАСОБИ РОЗВ'ЯЗАННЯ
ПОСТАВЛЕНИХ ЗАДАЧ
1.1 Опис предметної області
Додаток-каталог – веб-ресурс, де є необхідні дані про конкретний предмет,
а також представлені його характеристики та опис.
За своєю структурою додаток-каталог певною мірою схожий на книгу
рецептів. Але в порівнянні з більш масштабним проектом, каталог більш простий
в обслуговуванні, адже він не передбачає замовлення товару та його оплату
безпосередньо в додатку. Користувач програмного продукту для пришвидшення
власної роботи може швидко та без складнощів знайти потрібний йому напій та
приготувати його, прочитавши які інгредієнти потрібні для створення напою та
рецепт його приготування.
Проектування додатку-каталогу зосереджується на двох основних аспектах,
які роблять каталог успішним:
‒ інформативна частина картки напою;
‒ дизайн каталогу на основі UX-підходу для створення взаємовигідних
відносин між списком коктейлів та користувачем додатку.
До ключових функцій, які повинні бути реалізована у типовому додатку-
каталогу, належать такі:
‒ наявність детального опису приготування напою та його складові;
‒ наявність швидкого пошуку потрібного напою;
‒ надання можливості приготувати напій не тільки в барах.
Створення електронних каталогів напоїв вимагає попереднього вивчення
якісного та фізичного стану напоїв, запитів користувачів. Така діяльність
складається з процесів:
1 Класифікація напоїв. Напої доцільно розділити на категорії, такі як
гарячі та холодні, алкогольні та безалкогольні, кава та чай, соки, вино
тощо.
6
ЧДТУ 242063.017ПЗ
2 Складання списку напоїв. При створенні повного списку напоїв,
необхідно включити їхні назви, склад, посуд, з якого подається цей
напій.
3 Фотографування напоїв. До кожного напою необхідно додати базові
фотографії. Гарні зображення можуть викликати бажання випробувати
напій.
4 Формування опису напою. До кожного напою необхідно додати
короткий опис, який визначає його смак, аромат та інші характеристики.
5 Врахування технічних деталей, таких як вибір платформи, мови
програмування, фреймворку, створення інтерфейсу та проектування
бази даних.
6 Дизайн каталогу. Каталог проектувався таким чином, щоб він був
привабливим та легким для використання.
7 Актуалізація каталогу. Передбачається регулярне оновлення каталогу,
щоб відображати нові напої.
1.2 Актуальність розробки додатку-каталогу напоїв
Розробка мобільних додатків з каталогами напоїв може мати кілька
важливих переваг і причин, чому це залишається актуальним та важливим
напрямком:
1 Зручність для користувачів. Мобільні додатки надають зручний і
доступний інтерфейс для користувачів, дозволяючи їм легко
переглядати рецепти напоїв, готувати їх самостійно та взаємодіяти з
каталогом в будь-який час та з будь-якого місця.
2 Можливість розширення асортименту. Завдяки мобільним додаткам з
каталогами напоїв, підприємства можуть легко оновлювати та
розширювати свій асортимент, представляючи нові напої та
експериментуючи зі складами.
7
ЧДТУ 242063.017ПЗ
3 Збільшення продажів. Інтерактивний та зручний каталог дозволяє
ефективніше презентувати товари, що може призвести до збільшення
продажів.
4 Збирання відомостей про клієнтів. Завдяки обліку замовлень та
програмам лояльності, додатки дозволяють збирати важливі дані про
клієнтів, що може бути використано для персоналізації сервісу та аналізу
поведінки.
5 Взаємодія зі споживачем. Додатки надають можливість забезпечити
активну взаємодію зі споживачами через відгуки, оцінки, опитування та
зворотний зв'язок.
6 Конкурентна перевага. Наявність мобільного додатку може бути
конкурентною перевагою, оскільки він відображає готовність до
впровадження технологічних нововведень та забезпечення кращого
обслуговування клієнтів.
7 Тренди у споживчому ринку. Сучасні споживачі все частіше
користуються мобільними додатками для зручності та ефективності, що
робить їх популярними серед бізнесів у сфері харчової та напійної
промисловості.
Загалом, мобільні додатки із каталогами напоїв можуть виявитися важливим
інструментом для підвищення конкурентоспроможності підприємства та
забезпечення зручності для споживачів.
1.3 Огляд аналогів
Деякі ресторани використовують спеціалізовані електронні додатки для
барменів. Це може полегшити процес замовлення для клієнтів та спростити
управління меню для персоналу. Розглянемо перелік популярних електронних
додатків для ресторанів.
1 Tasty є популярною платформою для ресторанів. Цей додаток містить
колекцію абсолютно різних рецептів страв.
8
ЧДТУ 242063.017ПЗ
Рисунок 1.1 – Огляд аналогу додатку «Tasty»
2 Коктейлер – це додаток, де зібрані понад 1100 рецептів різноманітних
коктейлів
Рисунок 1.2 – Огляд аналогу додатку «Коктейлер»
9
ЧДТУ 242063.017ПЗ
1.4 Напрямки розробки сучасних мобільних додатків
Застосування штучного інтелекту та машинного навчання в мобільних
додатках стає все більш поширеним. Вони використовуються для персоналізації
змісту, розпізнавання образів, покращення прогностичного аналізу та
автоматизації завдань.
Також відбувається взаємодія мобільних додатків з різними IoT-
пристроями, такими як розумні пристрої вдома, носимі гаджети та інші "розумні"
об'єкти. Це може означати віддалене керування, моніторинг стану пристроїв та
збір інформації з сенсорів.
Розширює можливості мобільних додатків запровадження 5G,
забезпечуючи швидший і стабільніший доступ до мережі. Це впливає на
відеопотік, стрімінг, віртуальну та розширену реальність, а також ігри.
Нові можливості для взаємодії з користувачем надають AR і VR. Додатки
можуть використовувати AR для додавання віртуальних об'єктів до реального
світу, а VR - для створення іммерсивного середовища.
Прогресивні веб-додатки (PWA) поєднують переваги веб-сайтів і мобільних
додатків, забезпечуючи швидший доступ та роботу офлайн. Вони можуть
ефективно працювати на різних платформах.
Застосування блокчейну у мобільних додатках спрямоване на забезпечення
безпеки та прозорості у фінансових операціях, обміні даними та інших областях.
Зросли вимоги до захисту даних користувачів, що призводить до акценту на
заходах безпеки та захисті приватності.
Для покращення взаємодії з користувачем, розуміння контексту та надання
персоналізованих рекомендацій використовують технології обробки мови та
натуральної мови.
Тренди в мобільній розробці швидко змінюються, і важливо слідкувати за
інноваціями, щоб створювати сучасні та конкурентоспроможні додатки.
1.5 Постановка задачі
Інформаційна система, що розробляється, представляє собою мобільний
застосунок для пошуку та розгляду рецептів різних алкогольних та
10
ЧДТУ 242063.017ПЗ
безалкогольних напоїв (коктейлів). Сервіс може бути застосований як для робочих
процесів барів, так і для особистого користування. Отже, від системи вимагається:
- розробити клієнтську частину з інтуїтивно зрозумілим
інтерфейсом;
- розробити серверну частину, яка забезпечить швидку обробку
запитів користувачів;
- забезпечити сумісність з різними пристроями на операційній
системі Android;
11
ЧДТУ 242063.017ПЗ
ВИСНОВОК ДО ПЕРШОГО РОЗДІЛУ
У першому розділі було розглянуто додатки-аналоги, актуальність
розробки, аспекти постановки задач та напрямки розробки сучасних мобільних
додатків. У зв'язку з цим, було визначено основні завдання, необхідні для успішної
реалізації проєкту. До цих завдань належать:
Завдання 1: аналітичний огляд аналогів додатку.
Першим кроком у розробці мобільного додатку є проведення аналітичного
огляду існуючих аналогів. Це дозволяє виявити сильні та слабкі сторони
конкурентів, визначити найкращі практики та уникнути поширених помилок.
Важливо детально проаналізувати функціональні можливості, інтерфейс
користувача, технічні характеристики та відгуки користувачів інших додатків, які
виконують подібні функції. Цей етап допоможе сформулювати чіткі вимоги до
майбутнього продукту та забезпечити його конкурентоспроможність на ринку.
12
ЧДТУ 242063.017ПЗ
РОЗДІЛ 2 ВПРОВАДЖЕННЯ РЕЗУЛЬТАТІВ ДОСЛІДЖЕНЬ У
ПРАКТИКУ ПРОЕКТУВАННЯ ПРОГРАМНОГО ЗАБЕЗПЕЧЕННЯ
ІНФОРМАЦІЙНИХ СИСТЕМ
2.1 М оделювання предметної області
У цьому підрозділі розглядатиметься предметна область моделювання, її
модель, опис словника предметної області, елементи моделювання програмної
області та робоча область моделювання.
2.1.1 Предметна область моделювання. Модель предметної області.
Словник предметної області
Предметна область моделювання це поняття, яке охарактеризовує
сукупність задач, функцій та об’єктів, які дають можливість виконати поставлені
цілі.
Модель предметної області
Рисунок 2.1 – Модель предметної області
Словник предметної області – це набір термінів і визначень, що
використовуються для опису основних понять та концепцій у конкретній області
знань. Він слугує засобом уніфікації розуміння та комунікації між фахівцями, які
працюють у цій області.
Словник предметної області для каталогу напоїв, що розробляється
складається з таких понять:
13
ЧДТУ 242063.017ПЗ
1 Напій – це рідка або розчинена речовина, призначена для прийому
внутрішньо. Напої можуть бути алкогольними або безалкогольними.
2 Каталог напоїв – це список напоїв, який може містити їхні назви, опис,
ціни, фотографії, склад та іншу інформацію.
3 Гарячі напої – це напої, які призначені для вживання у гарячому стані,
такі як кава, чай, гарячий шоколад тощо.
4 Холодні напої – це напої, які подаються або призначені для вживання у
холодному стані, такі як холодні коктейлі, лимонади тощо.
5 Алкогольні напої – це напої, які містять алкоголь, такі як вино, пиво,
коктейлі тощо.
6 Безалкогольні напої – це напої, які не містять алкоголю, такі як
безалкогольні коктейлі, соки, газовані напої тощо.
7 Фотографія напою – це зображення напою, яке допомагає клієнтам
визначити його зовнішній вигляд.
8 Опис напою – це короткий текстовий опис характеристик та
особливостей напою.
9 Розмір порції – це об'єм або кількість напою, яка входить до однієї порції.
Цей словник предметної області надає базовий набір термінів для опису
каталогу напоїв та визначення ключових понять у цій галузі.
2.1.2 Елементи моделювання предметної області
Діаграми елементів моделювання
Для моделювання предметної області та при проектуванні системи як
правило використовується мова UML, яка дозволяє показати розроблювану
інформаційну систему в якості різних діаграм, як наприклад, діаграма класів,
діаграма станів, логічна діаграма тощо. Для цих діаграм існують три типи
позначень: графічні символи, єднальні елементи та текст.
2.1.3 Робоча область моделювання
14
ЧДТУ 242063.017ПЗ
Рисунок 2.2 – Зв’язки мови UML
Завдання робочої області моделювання полягає у тому, щоб чітко зрозуміти
основні бізнес-функції, з’ясувати вимоги, що пред’являються до інформаційної
системи. Для цього необхідно провести аналіз компанії і побудувати її повну
бізнес-модель. Як приклад, розглянемо сайт з підбором автозапчастин.
У кожного автомобіля є своя марка, модель та VIN код. Заходячи на сайт,
клієнт може підібрати запчастину по цим критеріям, також вказавши рік випуску
автомобіля. Також невід’ємною частиною є те, що кожна деталь має свій артикул.
Користувач може бачити фото деталі, виробника, вартість запчастини. Власник
авто також може скористуватись пошуком або каталогом сайту для знаходження
потрібної йому деталі з категорії.
Коли покупець робить замовлення, то це замовлення потрапляє в кошик,
куди можна скласти не одну запчастину, а одразу декілька на різні автомобілі
різних виробників. Після потрапляння в кошик покупець може очистити його,
видалити певні товари або зробити їхнє замовлення та оплатити.
Після оплати дані про замовлення надсилаються співробітнику магазину,
який в свою чергу буде збирати це замовлення та інформувати покупця про
15
ЧДТУ 242063.017ПЗ
можливість забрати товар у пункті видачі замовлення, це може бути окремий пункт
видачі з доставкою або магазин, або кур’єрська доставка, або доставка у відділення
пошти. У випадку доставки поштою, замовляється кур’єр, який доставить товар
до відділення пошти та відправить за потрібною адресою.
2.2 Формування та аналіз вимог
2.2.1 Формування вимог до програмного забезпечення. Первинні і детальні
вимоги. Вимоги замовника і розробника. Функціональні та нефункціональні
вимоги
Формування вимог до програмного забезпечення
Для роботи мобільного застосунку не потрібно мати потужний девайс.
Вимоги можуть змінюватися під час розширення функціоналу додатку, але
незначно. Загальні рекомендації по обладнанню полягають в наступному:
Процесор
‒ чотирьох або восьмиядерний процесор з тактовою частотою мінімум 1.8
ГГц.
Оперативна пам'ять (ОЗУ)
‒ мінімум 512 МБ ОЗУ.
Накопичувач
‒ вільної пам’яті повинно бути мінімум 50 МБ.
Мережевий інтерфейс
‒ стабільне з'єднання з Інтернетом зі швидкістю принаймні 1 Мбіт/с.
Вимоги для користувачів
Підтримувані платформи
‒ пристрій повинен мати операційну систему Android версії не нижче 5.0.
Первинні і детальні вимоги.
Первинні вимоги
‒ мобільний додаток має бути сумісним з версією операційної системи
Android 5.0;
16
ЧДТУ 242063.017ПЗ
‒ програмне забезпечення повинно мати сумісність з різними розмірами
екранів.
Детальні вимоги
‒ інтерфейс повинен бути інтуїтивно зрозумілим та зручним;
‒ інформація про напій повинна бути викладена у зрозумілому вигляді.
Вимоги замовника і розробника
Вимоги замовника:
‒ простий та інтуїтивно зрозумілий інтерфейс;
‒ можливість фільтрування по категоріям: алкогольні, безалкогольні;
‒ швидкий час завантаження додатку та рецепту.
Вимоги розробника:
‒ використання актуальних версій бібліотек;
‒ модульна архітектура мобільного додатку для легкого розширення
функціоналу;
‒ використання мови програмування Kotlin.
Функціональні та нефункціональні вимоги
Функціональні вимоги:
‒ перегляд фото та назви напою;
‒ перегляд рецепту приготування та інгредієнтів напою;
‒ мобільний додаток повинен використовувати API;
‒ забезпечення ефективної роботи додатка на різних присторях з
операційною системою Android та швидкі відповіді на запити
користувачів.
Нефункціональні вимоги:
‒ час завантаження не більше 30 секунд;
‒ безпека даних користувача;
‒ легкий пошук потрібного напою.
2.2.2 Формування вимог за допомогою діаграми прецедентів
Сформуємо вимоги до інформаційної системи каталогу напоїв у вигляді
діаграми прецедентів (варіантів використання) що зображено на рисунку 2.3.
17
ЧДТУ 242063.017ПЗ
Діаграма прецедентів є одним із видів діаграм в мові моделювання UML
(Unified Modeling Language). Ця діаграма використовується для візуалізації
функціональності системи та взаємодій між її різними частинами з точки зору
користувача.
Опишемо діаграму прецедентів інформаційної системи каталогу напоїв.
Діаграма прецедентів:
1 Актори:
‒ Користувач:
‒ Опис: Користувач додатку, який переглядає рецепти напоїв.
2 Прецеденти:
‒ Перегляд каталогу напоїв:
‒ Опис: Користувач може переглядати список напоїв, їх фотографії
та інші характеристики.
‒ Взаємодія: Користувач
‒ Результат: відображення каталогу напоїв.
‒ Перегляд деталей напою:
‒ Опис: Користувач може отримати детальну інформацію про
конкретний напій, таку як опис, інгредієнти, тощо.
‒ Взаємодія: Користувач
‒ Результат: відображення деталей обраного напою.
‒ Пошук:
‒ Опис: Користувач може швидко знайти напій, який його
цікавить.
‒ Взаємодія: Користувач
‒ Результат: відображення списку пропозицій шуканого напою.
18
ЧДТУ 242063.017ПЗ
Рисунок 2.3 – Нотація діаграми використання (прецедентів) інформаційної
системи каталогу напоїв
Це базова діаграма прецедентів, яка описує основні можливості користувача
у мобільному додатку з каталогом напоїв.
2.3 Проектування логічної структури інформаційної системи каталогу
напоїв
У цьому підрозділі описуватиметься діаграма класів та діаграма пакетів.
2.3.1 Діаграми класів
Діаграма класів є одним із видів діаграм в рамках мови моделювання UML
(Unified Modeling Language). Вона використовується для візуального
представлення структури та взаємозв'язків між класами в системі.
Клас визначає атрибути і методи набору об’єктів. Всі об’єкти цього класу
(екземпляри цього класу) мають спільну поведінку і однаковий набір атрибутів
(кожен з об’єктів має свій власний набір значень). Іноді замість назви «клас»
використовують назву «тип», але, слід зауважити, що ці назви описують різні речі:
тип є загальнішим визначенням.
19
ЧДТУ 242063.017ПЗ
Основні компоненти діаграми класів інформаційної системи каталогу напоїв
наведено на рисунку 2.4.
Рисунок 2.4 – Діаграма класів інформаційної системи каталогу напоїв
У UML класи позначаються прямокутниками з назвою класу, у цих
прямокутниках у вигляді двох «відсіків» може бути показано атрибути і операції
класу.
У UML атрибути показуються щонайменше назвою, також може бути
показано їх тип, початкове значення і інші властивості
Операції (методи) також показуються принаймні назвою, крім того, може
бути показано їх параметри і типи значень, які буде повернуто.
Діаграма класів дозволяє моделювати структуру системи та визначити, які
класи і як вони взаємодіють. Вона є потужним інструментом для розробників
програмного забезпечення, архітекторів та інженерів, щоб відобразити
концептуальні та структурні аспекти системи перед фактичною реалізацією.
20
ЧДТУ 242063.017ПЗ
Рисунок 2.5 – Вигляд діаграми класів з атрибутами для каталогу напоїв
На цій діаграмі класів зображені класи, які будуть використовуватись під
час розробки програмного продукту. Опис діаграми:
Клас «Картка напою» – в цьому класі потрібно відображати сам напій та його
категорію з викликом потрібних деталей.
Клас «Користувач» – потрібен для того, щоб ідентифікувати користувача та
в майбутньому відслідковувати який користувач під яким логіном зайшов і
використовує програмний продукт.
Клас «Категорія» - потрібен для фільтрації напоїв по категоріям
алкогольного та безалкогольного, тому має свій порядковий номер та назву з
методом отримання усіх напоїв обраної категорії.
Клас «Напій» - потрібен для збереження основної інформації обраного
напою та його характеристик (рецепту, фото, назви, інгрідієнтів та унікального
ідентифікатору)
Клас «Інгрідієнт» - потрібен для збереження інформації про інгрідієнт та
його кількість для приготування обраного напою.
21
ЧДТУ 242063.017ПЗ
2.3.2 Діаграма пакетів
Діаграма пакетів використовується для візуалізації організації та структури
коду великих програмних проєктів чи систем.
Рисунок 2.6 – Діаграма пакетів інформаційної системи каталогу напоїв
Як показано на рисунку 2.6 основними елементи діаграми пакетів
інформаційної системи каталогу напоїв є такі:
1 Пакет, який представляє собою контейнер для групування елементів
моделі, таких як класи, інтерфейси, підпакети тощо. Він допомагає
структурувати та організовувати компоненти системи.
2 Відношення "Включення" (Dependency) вказує на те, що один пакет
використовує функціональність іншого пакету. Це відношення
відображає залежності між пакетами.
3 Відношення "Вміст" (Containment) вказує, що один пакет містить інший.
Це відношення показує ієрархію між пакетами та їх вкладеність.
4 Імпорт пакету дозволяє використовувати елементи одного пакету в
іншому пакеті.
5 Псевдонім пакету (Package Alias) використовується для забезпечення
альтернативного імені для пакету у визначенні іншого пакету.
6 Стірлінгові стрілки (StereoType) стереотипи використовуються для
надання додаткової інформації про пакети.
22
ЧДТУ 242063.017ПЗ
2.4 Архітектурне проектування
У цьому підрозділі описуватиметься діаграма компонентів та розгортання
програмної системи на апаратних засобах з відповідною діаграмою розгортання
та її описом.
2.4.1 Діаграма компонентів
Діаграми компонентів відображає внутрішню структуру та взаємодію різних
системних компонентів проєкту. Ця діаграма призначена для надання
концептуального уявлення про архітектуру програмного забезпечення.
За наданою інформацією, дані, включаючи обліковий запис та ідентифікатор
перевірки, надходять у компонент через порт з правого боку. Цей компонент тоді
перетворює дані у формат, зрозумілий внутрішнім компонентам системи.
Інтерфейси праворуч відомі як необхідні інтерфейси, які відображають послуги,
необхідні для виконання компонентом своїх функцій (рисунок 2.7).
Рисунок 2.7 – Діаграма компонентів інформаційної системи каталогу напоїв
Діаграма компонентів відзначається тим, що компоненти є автономними. Це
означає, що вони можуть бути замінені на альтернативні, і вони мають свої
інтерфейси, через які взаємодіють з іншими компонентами.
Кожен компонент має свої інтерфейси, через які він взаємодіє з іншими
компонентами. Інтерфейси також відображають зв’язки та залежності в
архітектурі програмного забезпечення.
23
ЧДТУ 242063.017ПЗ
Дані проходять через з’єднання до кількох інших компонентів перед
виведенням їх на порти ліворуч. Це відбувається через надані інтерфейси, які
вказують на послуги, які надає компонент.
Велика квадратна форма може визначати систему або підсистему, яка оточує
внутрішні компоненти. Це важливо для визначення організації та ієрархії в
системі.
Загальна діаграма компонентів UML надає нам зрозуміле уявлення про
структуру системи та взаємодії між її компонентами. Це розуміти та управляти
архітектурою програмного забезпечення, забезпечуючи при цьому модульність та
гнучкість у роботі з компонентами.
2.4.2 Розгортання програмної системи на апаратних засобах. Діаграма
розгортання
Діаграми розгортання використовуються для візуалізації топології фізичних
компонентів системи, де розгорнуті програмні компоненти (рисунок 2.8).
Діаграма розгортання, як і діаграма компонентів, є складовою частиною
фізичного представлення моделі і розробляється, як правило, для територіально
розподілених систем. Вона відображає фізичні взаємозв'язку між програмними та
апаратними компонентами системи, що розробляється і є хорошим засобом
представлення маршрутів переміщення об'єктів і компонентів в розподіленої
системі.
При розробці діаграми розгортання слід дотримуватися наступних правил та
рекомендацій.
1 Перед розробкою діаграми необхідно ідентифікувати:
‒ категорії (типи) користувачів (для кожної категорії повинні бути
визначені кількість користувачів та необхідні для роботи компоненти
системи);
‒ апаратні, технічні та інші типи пристроїв, необхідні для виконання
системою своїх функцій;
‒ види і необхідну пропускну здатність каналів зв'язку.
24
ЧДТУ 242063.017ПЗ
2 Повинні бути розглянуті варіанти прокладки нової або модернізації
існуючої корпоративної мережі організації.
3 З метою наочного уявлення розподіленої інформаційної системи на
діаграмі рекомендується відображати компоненти, інтерфейси та зв'язку
між ними.
Рисунок 2.8 – Діаграма розгортання інформаційної системи каталогу напоїв
2.5 Моделювання поведінки системи
Моделювання поведінки системи - це процес створення абстрактних
представлень, які описують, як система взаємодіє з іншими елементами, а також
як вона реагує на події і зміни в своєму оточенні. Це важливий етап при розробці
програмного забезпечення та архітектурі систем.
При моделювання поведінки інформаційної системи каталогу напоїв були
створені діаграма послідовності, діаграма діяльності та діаграма комунікації
(рисунок 2.9 – 2.11).
2.5.1 Діаграма діяльності
25
ЧДТУ 242063.017ПЗ
Діаграма діяльності – це тип діаграми, яка використовується для візуалізації
та моделювання взаємодії між об'єктами в системі. Діаграми діяльності
допомагають визначити, як об'єкти спілкуються між собою для досягнення
певного функціоналу.
Основні елементи діаграм взаємодії включають об'єкти, повідомлення
(виклики та відповіді), фрейми (для визначення контексту або групування
повідомлень) та різноманітні конструкції для визначення умов, ітерацій та інших
аспектів взаємодії (рисунок 2.9).
Рисунок 2.9 – Діаграма діяльності покупця із каталогом напоїв
Ці діаграми стають важливим інструментом під час аналізу та проектування
систем, де необхідно розібрати та відобразити взаємодію об'єктів для досягнення
конкретного функціоналу чи бізнес-процесу.
2.5.2 Діаграма послідовності
Діаграма послідовності використовується для візуалізації взаємодії між
різними об'єктами в системі протягом певного часу, показуючи послідовність
викликів та відповідей між об'єктами.
26
ЧДТУ 242063.017ПЗ
Кожен об'єкт представлений в діаграмі піктограмою, яка зазвичай має ім'я та
прямокутник або інший символ, що визначає область життєвого циклу об'єкта.
Лінії життєвого циклу на діаграмах представляють часовий період, протягом
якого об'єкт існує або виконує конкретну дію. Лінії життєвого циклу виходять з
піктограм об'єктів та показують, коли об'єкт активний.
Виклики та повернення відображаються як стрілки між об'єктами.
Стрілки вказують на напрямок виклику, ініціатора та отримувача.
Фрейми використовуються для виділення певних частин діаграми та
позначення умов, ітерацій чи альтернативних варіантів виконання.
Збіжність та розділення показують збіг або розділення виконання в діаграмі.
Збіжність вказує на те, що кілька шляхів діаграми збігаються в одну точку.
Розділення вказує на розгалуження виконання.
Рисунок 2.10 – Діаграма послідовності сценарію
«Пошук напою»
2.5.3 Діаграма комунікації
Діаграма комунікації подібна до діаграми послідовності, але більше
акцентується на взаємодії між об'єктами у конкретний момент часу. Об'єкти
27
ЧДТУ 242063.017ПЗ
представлені у вигляді прямокутників, і лінії взаємодії показують напрямок та
характер цієї взаємодії. Використовується для відображення загальної структури
системи та взаємодії між її частинами.
Рисунок 2.11 – Діаграма скінченого стану обробки бізнес-процесу в
інформаційній систем каталогу напоїв
Діаграма скінченого стану дозволяє вам візуалізувати та аналізувати логіку
та порядок подій в бізнес-процесі. Вона особливо ефективна для відображення
сценаріїв, в яких система або процес може знаходитися в різних станах та
реагувати на події.
28
ЧДТУ 242063.017ПЗ
ВИСНОВОК ДО ДРУГОГО РОЗДІЛУ
У другому розділі було розглянуто впровадження результатів дослідження,
описаних у першому розділі. Особлива увага була приділена моделюванню
предметної області, а також аналізу та формуванню функціональних і
нефункціональних вимог до розроблюваного програмного забезпечення за
допомогою UML
Моделювання предметної області включало визначення основних
компонентів системи, їх атрибутів, методів та взаємозв'язків. Було розроблено
UML діаграми класів, які відображають структуру системи, що дозволило виявити
всі необхідні елементи та їхні взаємодії. Це допомогло у створенні чіткої та
зрозумілої архітектури додатку.
Аналіз та формування функціональних вимог було спрямоване на
визначення основних функцій, які повинен виконувати додаток. Було враховано
всі бізнес-вимоги та очікування користувачів, що дозволило створити перелік
необхідних функцій та визначити їх пріоритетність. Для цього використовувалися
такі UML діаграми, як діаграми прецедентів, які відображають взаємодію
користувачів із системою.
Нефункціональні вимоги включали аспекти продуктивності, безпеки,
надійності та зручності використання. Для їх аналізу та формування також
використовувалися UML діаграми, такі як діаграми активностей і станів, що
дозволило детально опрацювати поведінку системи у різних ситуаціях та
забезпечити відповідність вимогам як
Таким чином, другий розділ забезпечив комплексний підхід до
впровадження результатів досліджень, виконаних у першому розділі.
Моделювання предметної області та використання UML діаграм для аналізу і
формування функціональних і нефункціональних вимог дозволили створити
детальний план розробки програмного забезпечення. Це забезпечить відповідність
майбутнього додатку бізнес-вимогам і очікуванням користувачів, а також високий
рівень якості.
29
ЧДТУ 242063.017ПЗ
РОЗДІЛ 3 РОЗРОБКА ТА ТЕСТУВАННЯ ПРОГРАМНОГО
ЗАБЕЗПЕЧЕННЯ
3.1 Розробка програмного комплексу
У цьому підрозділі розглядатиметься обґрунтування вибору засобів
реалізації програмного продукту, опис структурної схеми, опис логічної схеми,
розробка бази даних, розробка інтерфейсу програмного засобу та опис розробки
програмних компонентів
3.1.1 Обґрунтування вибору засобів реалізації
Для розробки мобільного додатку використовується одна з двох мов
програмування: Java та Kotlin. Для розробки даного програмного продукту я обрав
мову програмування Kotlin, оскільки ця мова має багато переваг, деякі з них
наведені нижче:
‒ більш сучасний та лаконічний синтаксис мови програмування;
‒ підтримка корутин – засобів асинхронного програмування;
‒ сумісність з Java;
‒ має вбудовані функції підвищення безпеки додатків.
Також нам потрібно обрати середовище розробки. З доступних є Android
Studio, Visual Studio Code та Xcode.
В межах даного проекту визначено, що це буде мобільний додаток для операційної
системи Android, тому було обрано середовище розробки Android Studio. З переваг
можна виразити наступне:
‒ зрозумілий інтерфейс;
‒ підтримка напряму від Google;
‒ IDE створено лише для розробки на Android;
‒ має вбудовану підтримку Git;
‒ має підтримку системи автоматичної збірки проекту Gradle.
Для реалізації графічного інтерфейсу використовуватимуться вбудований
графічний конструктор Android Jetpack Compose.
30
ЧДТУ 242063.017ПЗ
Рисунок 3.1 - Приклад середовища розробки Android Studio
Також під час розробки будуть використовуватись такі бібліотеки:
Kotlin Corutines – бібліотека, призначена для написання блоків коду, які
будуть працювати асинхронно під час виконання інших блоків коду.
Retrofit – бібліотека, що дозволяє працювати з REST API, відправляти
запити на сервер та отримувати їх у форматі JSON.
GSON – бібліотека, що дозволяє обробляти JSON запити, перетворюючи їх
в об’єкти або типи, наприклад, String, int та інші, а також перетворювати типи
даних в JSON формат для подальшого формування запиту.
Glide – бібліотека, що дає змогу працювати з файлами зображень різних
форматів.
Виходячи з вищесказаного, для реалізації програмного продукту буде
використовуватись мова програмування Kotlin, середовище розробки Android
Studio та вбудований функціонал середовища розробки для створення графічного
інтерфейсу додатку.
3.1.2 Опис структурної (функціональної) схеми
В структурній схемі показаний основний зміст компонентів розроблюваної
програми (рисунок 3.2). На даній схемі зображено:
31
ЧДТУ 242063.017ПЗ
- частина виду користувача (View), на якій описані класи, що відповідають
за графічний показ елементів додатку;
- частина моделі (ViewModel), яка дає можливість користувачу працювати
з серверною частиною та отримувати необхідну інформацію;
- серверна частина (Model), яка приймає запит від користувача через
обробник запитів (ViewModel) та оброблює його, шляхом відсилання
запиту на сервер, отримання даних від нього, та їхня обробка для
повернення у інтерфейсну частину.
Рисунок 3.2 – Структурна діаграма мобільного додатку
3.1.3 Опис логічної схеми системи
На рисунку 3.3 показана логічна схема роботи програмного забезпечення.
Це дає нам зрозуміти принцип роботи додатку. Користувач під час натискання на
плитку з обраним напоєм переходить на сторінку з його деталями, а саме: назва
напою, рецепт напою, необхідні інгредієнти для його приготування та спосіб
32
ЧДТУ 242063.017ПЗ
подачі. Після натискання на картку напою передається id напою в ViewModel, де
формується запит в обробник подій, який в свою чергу подає запит в API, з якого
отримує інформацію, оброблює її та повертає отриманий результат у ViewModel,
в якому вже формується запит для формування сторінки з деталями та її
відображення. Після чого сформований фрагмент відображається та показує
результат.
Рисунок 3.3 – Логічна схема системи
3.1.4 Розробка бази даних
Для прискорення та полегшення розробки програмного забезпечення було
прийнято рішення використовувати API – прикладного програмного
забезпечення.
API (прикладне програмне забезпечення) – це спосіб завдяки якому дві або
більше компʼютерні програми можуть спілкуватися між собою.
Набір визначень підпрограм, протоколів взаємодії та засобів для
створення програмного забезпечення.
Для реалізації цього додатку було використано прикладне програмне
забезпечення вільного доступу під назвою “TheCocktailDB” (рисунок 3.4). Ця
система працює по принципу серверу, що приймає запит та надає відповідь, але
33
ЧДТУ 242063.017ПЗ
відповідь надається у форматі JSON, який вже опрацьовується в серверній частині
додатку для нормального подання користувачу.
Рисунок 3.4 – Веб-сторінка з посиланнями на API
В цьому API є своя база даних, в якій зберігаються дані про напої:
Напої (Drinks)
‒ idDrink: унікальний ідентифікатор напою (число, обов’язкове,
унікальне)
‒ strDrink: назва напою (строка, обов’язкове)
‒ strAlcoholic: тип напою (алкогольний чи безалкогольний) (строка,
обов’язкове)
‒ strInstructions: рецепт приготування (строка, обов’язкове)
‒ strDrinkThumb: посилання на фото напою (строка, обов’язкове)
‒ strIngredient1 - strIngredient15: інгредієнт, необхідний для приготування
напою (строка або null, обов’язкове)
‒ strMeasure1 – strMeasure2: пропорції відповідно до інгредієнтів (строка,
обов’язкове)
‒ strGlass: посуд, в якому подається напій (строка, обов’язкове)
‒ strImageSource: посилання оригінального зображення (строка,
обов’язкове)
34
ЧДТУ 242063.017ПЗ
За допомогою такої схеми формується JSON запит і відправляється разом з
даними в модуль обробки цього запиту серверною частиною мобільного додатку.
3.1.5 Розробка інтерфейсу користувача
Для розробки інтерфейсу користувача використовувалась дизайн-система
Material Design 3, розроблена компанією Google, а також пакет Android Jetpack
Compose. Сам графічний дизайн спроектовано в Figma, після чого реалізовано у
якості програмного забезпечення для операційної системи Android.
Рисунок 3.5 – Головна сторінка програмного забезпечення
На цій сторінці відображений список коктейлів за допомоги окремих карток,
також нижня панель навігації з кнопками «Головна(Home)» та «Каталог». Також
на головній сторінці знаходиться пошуковий рядок.
Додаток не потребує реєстрації та авторизації, що прискорює можливість
його застосування.
35
ЧДТУ 242063.017ПЗ
Рисунок 3.6 – Вікно каталогу
В цьому вікні користувач може вручну знайти потрібний йому напій, або
скористуватись пошуковим рядком, щоб не повертатись на головне меню.
Користувач може обрати категорію напою, таку, як алкогольний коктейль чи
безалкогольний та передивитись його деталі, які включають в себе інгредієнти,
рецепт та спосіб серверування (посудина).
Як видно з рисунку 3.7, таким чином виглядає картка напою. На ній ми
можемо переглянути назву напою, його зображення, необхідні інгредієнти для
його приготування, рецепт його приготування та посудина, у якій його слід
подавати.
36
ЧДТУ 242063.017ПЗ
Рисунок 3.7 – Картка напою
3.1.6 Опис розробки програмних компонентів
Створення програмних компонентів є невід’ємною частиною розробки
сучасних інформаційних систем. У цьому контексті програмні компоненти – це
основні класи, модулі, елементи системи, які тісно пов’язані між собою та
співпрацюють для надання інформаційній системі функціональності та
продуктивності. Перед початком створення цих компонентів потрібно розуміти
основні цілі та задачі проекту, які повинні робити створені компоненти, а також
чітко поставити функціональні вимоги для кожного компоненту інформаційної
системи.
Застосування об’єктно-орієнтованого програмування: базова основа для
конструювання майже будь-якої інформаційної системи. Використання цієї
стратегії допомагає симулювати реальні об’єкти, їхні властивості та можливості,
роблячи код більш зрозумілим та легко змінюваним. Кожен компонент є окремим
37
ЧДТУ 242063.017ПЗ
об’єктом, який має свої властивості та методи, що допомагає створити повноцінну
модульну архітектуру зі своїм набором об’єктів, які виконують поставлені перед
ними задачі.
Застосування шаблону проектування Model-View-ViewModel (MVVM): дає
нам можливість чітко розмежувати проект на три рівні частини:
- Model – основна логіка програми (серверна частина), у якій проводяться
всі обчислення, робота з даними, відправка/прийом запитів;
- View – вид (користувацький інтерфейс), графічна оболонка програмного
продукту;
- ViewModel – модель, яка представляє собою прошарок між
користувацьким інтерфейсом та серверною частиною, вирішуючи що
робити в серверній частині, а що відображати в користувацькому
інтерфейсі.
3.2 Тестування системи
У цьому розділі буде розглянуто декілька видів тестувань, а саме: модульне,
інтеграційне, системне та приймальне. Спочатку розглядатиметься модульне
тестування, яке перевіряє правильність роботи складових програмного
забезпечення, а саме: модулі, компоненти, функції. Далі буде проводитись
інтеграційне тестування, яке перевіряє правильність взаємодії між різними
модулями та компонентами системи. Після цього буде проведено системне
тестування, шо дасть розуміння про те, як працює програмне забезпечення в
цілому. Потім буде проводитись приймальне тестування, що включає в себе
перевірку програмного забезпечення на відповідність системи вимогам та
специфікаціям.
3.2.1 Модульне тестування
Для створення інформаційної системи каталогу напоїв використовувалась
мова Kotlin з шаблоном проектування Model-View-ViewModel, а також різні
бібліотеки.
38
ЧДТУ 242063.017ПЗ
Основна мета інформаційної системи полягає у можливості перегляду
рецепту конкретного напою або коктейлю.
Таблиця 3.1
Модульне тестування
Модуль Призначення Результат
IngredientsAdapter Приймання інформації з Модуль працює
інгрідієнтом та його належним чином
відображення в заданому місці
CocktailModel Приймання вхідної інформації Модуль працює
з id напою та відправка запиту належним чином
на сервер
CocktailDetailsActivity Відображає сторінку з Модуль працює
деталями напою належним чином
BaseViewModel Модуль розподілення даних Модуль працює
між AlcoholViewModel та належним чином
NonAlcoholViewModel
CatalogFragment Модуль для відображення вікна Модуль працює
каталогу належним чином
HomeFragment Модуль для відображення Модуль працює
даних головної сторінки належним чином
Всі основні модулі програмного забезпечення в ході тестування показали
хороші результати та працюють належним чином.
3.2.2 Інтеграційне тестування
Даний вид тестування перевіряє правильність взаємодії між компонентами
системи та веб сервером надавача API.
39
ЧДТУ 242063.017ПЗ
Таблиця 3.2
Ітераційне тестування
Компонент Результат
HomeFragment Компонент працює належним чином та
правильно передає інформацію у модуль
HomeViewModel
HomeViewModel Компонент працює належним чином та
правильно передає id напоїв у
CocktailModel
CocktailModel Компонент працює належним чином та
правильно формує і передає запит на
сервер після чого приймає його та передає
далі до обробки
ApiCocktailsAdapter Компонент працює належним чином та
правильно формує масив з даними для
відображення коктейлю
TabCocktailAdapter Компонент працює належним чином та
правильно використовує дані з масиву для
створення відображуваного фрагменту на
сторінці
Основні модулі системи, що впливають на працездатність інформаційної
системи було протестовано та не виявлено жодних помилок в їх роботі.
3.2.3 Системне тестування
Системне тестування дає можливість зрозуміти правильну роботу на рівні
всієї інформаційної системи, щоб переконатись, що вона відповідає всім вимогам,
закладеним при проектуванні програмного забезпечення.
40
ЧДТУ 242063.017ПЗ
Таблиця 3.3
Системне тестування
Модуль Протестовано Працює Опис дії
HomeActivity Так Так Відображає
головну сторінку
з категорійними
напоями
CocktailDetails Так Так Відображає
сторінку з
деталями
обраного напою
CocktailModel Так Так Формує запит для
відправки на
сервер
CatalogFragment Так Так Відображає
сторінку з
каталогом напоїв
ApiCocktailsAdapter Так Так Формує масив з
отриманими
ланими
Всі функції пройшли системне тестування та відповідають усім вимогам та
критеріям, поставленим під час проектування інформаційної системи
3.2.4 Приймальне тестування
Мета: Перевірка функціональності інформаційної системи з точки зору
користувача.
1 Перевірка коректного відображення обраних напоїв: недоліків не
знайдено.
41
ЧДТУ 242063.017ПЗ
2 Швидкість роботи інформаційної системи: деталі напоїв відображаються
швидко.
3 Інтуїтивність інтерфейсу: користувачі легко освоюють роботу з
додатком.
4 Зворотній зв’язок та пропозиції
Загальна оцінка:
Система працює стабільно без збоїв та виконує усі функції, які були
сформовані по технічному завданню та згідно вимог проектування. З точки зору
користувача мобільний застосунок вважається зручним та зрозумілим для
використання.
3.3 Приклади впровадження програмного комплексу
Головною ціллю бакалаврської роботи є впровадження програмного
продукту в реальний світ, але замовником було вирішено прийти до розширення
функціоналу та впровадити систему статистики найчастіше переглянутих напоїв,
щоб контролювати в закладах харчування найчастіше замовлювані напої та
вивести цей додаток окремо для бізнесу та побутових користувачів.
Запуск такої схеми надасть як замовнику, тка і розробнику можливість мати
більш обширну аудиторію користувачів цієї системи.
42
ЧДТУ 242063.017ПЗ
ВИСНОВКИ ДО ТРЕТЬОГО РОЗДІЛУ
У третьому розділі детально розглянуто процес розробки програмного
забезпечення для мобільного додатку-каталогу рецептів напоїв. Проектування
розпочалося з визначення основних функціональних та нефункціональних вимог,
які є критичними для успішної реалізації продукту.
Функціональні вимоги охоплюють основні дії, які користувачі можуть
виконувати у додатку. До них належать:
Перегляд каталогу напоїв: Користувачі можуть переглядати список
доступних рецептів напоїв, відфільтрованих за категоріями:
‒ детальний перегляд рецепту: Користувачі можуть переглядати
детальну інформацію про кожен напій, включаючи опис, рецепт, інгредієнти та
фото;
‒ пошук напоїв: Користувачі можуть шукати напої за назвою або
ключовими словам.
Нефункціональні вимоги визначають якісні аспекти програмного
забезпечення, такі як:
‒ продуктивність: Додаток повинен швидко реагувати на дії
користувача, з мінімальною затримкою при завантаженні даних.
‒ інтуїтивний інтерфейс: Користувацький інтерфейс повинен бути
простим і зрозумілим, забезпечуючи легкість навігації та використання функцій
додатку.
Для розробки програмного забезпечення було прийнято рішення
використовувати наступні засоби:
‒ мова програмування: Основною мовою програмування стала Kotlin для
Android.
‒ фреймворки та бібліотеки: Для швидкої розробки та підтримки
сучасного функціоналу було використано фреймворк Jetpack Compose для Android.
43
ЧДТУ 242063.017ПЗ
Тестування проект було ретельно протестовано на всіх етапах розробки,
включаючи:
‒ модульне тестування: кожен окремий модуль додатку було протестовано
на правильність роботи та відповідність вимогам;
‒ інтеграційне тестування: перевірено взаємодію між різними модулями та
компонентами системи;
‒ системне тестування: проведено комплексне тестування всієї системи в
цілому для виявлення можливих помилок та несправностей;
‒ приймальне тестування: додаток було протестовано в реальних умовах
використання, щоб перевірити, чи відповідає він очікуванням кінцевих
користувачів.
44
ЧДТУ 242063.017ПЗ
ВИСНОВОК
В ході розробки мобільного додатку-каталогу рецептів напоїв було
проведено комплексну роботу, яка охоплювала декілька важливих етапів.
У першому розділі було здійснено аналітичний огляд існуючих аналогів
додатку, що дозволило виявити їхні сильні та слабкі сторони, визначити найкращі
практики та уникнути поширених помилок.
У другому розділі розглянуто впровадження результатів дослідження,
описаних у першому розділі. Особлива увага була приділена моделюванню
предметної області, аналізу та формуванню функціональних і нефункціональних
вимог за допомогою UML. Було розроблено UML діаграми класів, діаграми
прецедентів, діаграми активностей і станів, що допомогло у створенні чіткої
архітектури додатку та забезпечило його відповідність бізнес-вимогам і
очікуванням користувачів.
У третьому розділі детально розглянуто процес розробки програмного
забезпечення. Було визначено основні функціональні та нефункціональні вимоги,
обрано мову програмування Kotlin та фреймворк Jetpack Compose для Android.
Проведено ретельне тестування на всіх етапах розробки, включаючи модульне,
інтеграційне, системне та приймальне тестування, що забезпечило високу якість
кінцевого продукту.
Було також розроблено інтерфейсну частину користувача, створено дизайн,
структуру екранів та інтерактивні компоненти, що забезпечують зручність та
інтуїтивність взаємодії з додатком. Крім того, розроблено серверну частину, яка
включала базу даних, серверне програмне забезпечення, API для взаємодії з
клієнтською частиною та механізми автентифікації та авторизації користувачів.
Загалом, виконання зазначених завдань дозволило створити
конкурентоспроможний, функціональний та надійний мобільний додаток, який
відповідає вимогам користувачів та сучасним стандартам якості.
45
ЧДТУ 242063.017ПЗ
СПИСОК ВИКОРИСТАНИХ ДЖЕРЕЛ
1 Уніфікована мова моделювання (Unified Modeling Language - UML).
URL: https://www.maxzosim.com/unifikovana-mova-modeluvannia/
2 Мова програмування Kotlin: URL: https://kotlinlang.org/
3 Kotlin для Android: URL: https://developer.android.com/kotlin
4 Архітектура розробки MVVM (Model-View-ViewModel) URL:
https://learn.microsoft.com/en-us/dotnet/architecture/maui/mvvm
5 Шаблон проектування MVVM (Model-View-ViewModel) для Android
URL: https://www.scaler.com/topics/android/mvvm-architecture-android/
6 Бібліотека Glide Image Loader для Android
URL:https://www.geeksforgeeks.org/image-loading-caching-library-android-
set-2/
7 Бібліотека Retrofit для роботи з REST API в Android URL:
https://www.geeksforgeeks.org/how-to-get-data-from-api-using-retrofit-
library-in-android/?ysclid=lx28t1fwh6828325731
8 Уніфікована мова програмування UML URL:
https://systems.education/who-uses-uml?ysclid=lx28ulf0b4256825696
9 Елементи UML діаграм URL: https://docs.kde.org/trunk5/uk/umbrello
/umbrello/uml-elements.html
10 API (Application Programming Interface) URL:
https://dbpedia.org/page/API
11 Коктейлер URL: https://captain-droid.com/apps/reading/kokteyler-1100-
kokteyley/
12 Tasty. URL: https://pdalife.to/tasty-android-a38729.html?ysclid=lx29stsu6
u68660604
13 Що таке веб-сервіс та їх види? [Електронний ресурс]. - Режим доступу:
https://2ip.ua/ua/blog/web-services.
14 Що таке веб-сервіс та їх види? [Електронний ресурс]. - Режим доступу:
https://2ip.ua/ua/blog/web-services.
15 What are Web services? [Електронний ресурс]. - Режим доступу:
https://www.techtarget.com/searchapparchitecture/definition/Web-services.
46
ЧДТУ 242063.017ПЗ
16 What is a RESTful API? [Електронний ресурс]. - Режим доступу:
https://aws.amazon.com/ru/what-is/restful-api/.
17 LPU аналіз вимог [Електронний ресурс]. - Режим доступу:
https://comp.ucoz.net/TSPP/KursRob/LPUAnalizVymog15.pdf.
18 UML діаграми випадків використання [Електронний ресурс]. - Режим
доступу: https://lvivqaclub.blogspot.com/2008/10/use-case-uml-
diagram.html.
19 Діаграми класів [Електронний ресурс]. - Режим доступу:
https://ua5.org/oop/392-diagrami-klasiv.html.
20 Теоретичні основи UML діаграм [Електронний ресурс]. - Режим доступу:
https://studfile.net/preview/16869580/page:5/.
21 UML діаграми компонентів [Електронний ресурс]. - Режим доступу:
https://www.mindonmap.com/uk/blog/uml-component-diagram/.
22 Документація Python [Електронний ресурс]. - Режим доступу:
https://www.python.org/doc/.
23 Flask документація [Електронний ресурс]. - Режим доступу:
https://flask.palletsprojects.com/en/3.0.x/.
24 Куницька С. Ю., Сергієнко О. С. Аспекти та практичне використання
засобів і функцій flask framework для забезпечення web-додатку.
[Електронний ресурс]. - Режим доступу: https://sci-conf.com.ua/wp-
content/uploads/2023/11/GLOBAL-SCIENCE-PROSPECTS-AND-
INNOVATIONS-2-4.11.23.pdf.
25 Сергієнко О.С., Потапенко Л.В. Usage of Flask framework tools and
functions for user’s communication with a web application. [Електронний
ресурс]. - Режим доступу: http://csbc.edu.ua/documents/student/110424.pdf.
26 Основи HTML [Електронний ресурс]. - Режим доступу:
https://developer.mozilla.org/ru/docs/Learn/Getting_started_with_the_web/H
TML_basics.
27 Основи CSS [Електронний ресурс]. - Режим доступу:
https://developer.mozilla.org/ru/docs/Learn/Getting_started_with_the_web/C
SS_basics.
28 JavaScript [Електронний ресурс]. - Режим доступу:
https://uk.wikipedia.org/wiki/JavaScript.
29 Вступ до JavaScript [Електронний ресурс]. - Режим доступу:
https://uk.javascript.info/intro.
47
ЧДТУ 242063.017ПЗ
30 Що таке Bootstrap? [Електронний ресурс]. - Режим доступу:
https://www.techtarget.com/whatis/definition/bootstrap.
31 Про PostgreSQL [Електронний ресурс]. - Режим доступу:
https://www.postgresql.org/about/.
32 Модель-Vid-Контроллер [Електронний ресурс]. - Режим доступу:
https://uk.wikipedia.org/wiki/%D0%9C%D0%BE%D0%B4%D0%B5%D0
%BB%D1%8C-%D0%B2%D0%B8%D0%B4-
%D0%BA%D0%BE%D0%BD%D1%82%D1%80%D0%BE%D0%BB%D0
%B5%D1%80.
33 Документація Visual Studio Code [Електронний ресурс]. - Режим доступу:
https://code.visualstudio.com/docs.
34 Кваліфікаційна робота бакалавра (нове ПЗАС 2023) [Електронний
ресурс].
35 Що таке тестування програмного забезпечення? [Електронний ресурс]. -
Режим доступу: https://university.sigma.software/what-is-software-testing/.
36 Інтеграційне тестування [Електронний ресурс]. - Режим доступу:
https://qalight.ua/baza-znaniy/integratsijne-testuvannya/.
37 Системне тестування [Електронний ресурс]. - Режим доступу:
https://qalight.ua/baza-znaniy/sistemne-testuvannya/.
38 Приймальне тестування [Електронний ресурс]. - Режим доступу:
https://qalight.ua/baza-znaniy/prijmalne-testuvannya/.
39 Модульне тестування [Електронний ресурс]. - Режим доступу:
https://qalight.ua/baza-znaniy/modulne-testuvannya/.
40 Launch your own REST API using Flask and Python [Електронний ресурс].
- Режим доступу: https://towardsdatascience.com/launch-your-own-rest-api-
using-flask-python-in-7-minutes-c4373eb34239.
41 Архітектура PostgreSQL [Електронний ресурс]. - Режим доступу:
https://www.educba.com/postgresql-architecture/.
42 Методичні рекомендації до підготовки кваліфікаційної роботи бакалавра
для здобувачів вищої освіти зі спеціальності 121 «Інженерія програмного
забезпечення» усіх форм навчання [Текст] /Укл.: Голуб С.В., Заспа Г.О.,
Куницька С.Ю., Півень О.Б. Катаєва Є.Ю., Салапатов В.І., Метелап В.В.,
Олексюк В.В.; М-во освіти і науки України, Черкас, держ. технол. ун-т. -
Черкаси : ЧДТУ, 2023. - 96 с.
48
ЧДТУ 242063.017ПЗ
ДОДАТОК А
ЗАТВЕРДЖЕНО:
Зав. кафедрою ПЗАС, професор
_________________ Голуб С.В.
„____” ______________ 2024 р.
Проектування інформаційної системи каталогу напоїв
Специфікація
482. ЧДТУ 242063.017ПЗ
Листів 2
Розробник ________________ Шраменко В.М.
Керівник ________________ Куницька С.Ю.
2024
49
ЧДТУ 242063.017ПЗ
Позначення Найменування Примітка
Документація
482.ЧДТУ. 242238 12 01 Текст програми
482.ЧДТУ. 242238 34 01 Інструкція користувачеві
482.ЧДТУ. 242238 90 01 Графічні матеріали
50
ЧДТУ 242063.017ПЗ
ДОДАТОК Б
Проектування інформаційної системи каталогу напоїв
Лістинг програм
482.ЧДТУ. 242063 12 01
Листів 49
Розробник ________________ Шраменко В.М.
2024
51
ЧДТУ 242063.017ПЗ
Лістинг CocktailDetailsActivity.kt
package com.example.cocktailmenu.activity
import android.annotation.SuppressLint
import android.content.ContentValues.TAG
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.ImageView
import android.widget.TextView
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.example.cocktailmenu.adapter.IngredientsAdapter
import com.example.cocktailmenu.R
import com.example.cocktailmenu.viewModel.CocktailDetailsViewModel
open class CocktailDetailsActivity : AppCompatActivity() {
@SuppressLint("MissingInflatedId")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_cocktail_details)
val detailsViewModel: CocktailDetailsViewModel
val cocktailName: TextView = findViewById(R.id.cocktail_name)
val imageCocktail: ImageView = findViewById(R.id.cocktail_image)
val idDrink = intent.getStringExtra("idDrink")
52
ЧДТУ 242063.017ПЗ
val ingredientsRecycler =
findViewById<RecyclerView>(R.id.ingredients_recycler)
val instruction: TextView = findViewById(R.id.instruction_details)
val serve: TextView = findViewById(R.id.serve_info)
detailsViewModel = ViewModelProvider(
this,
viewModelFactory { CocktailDetailsViewModel(idDrink!!) }
)[CocktailDetailsViewModel::class.java]
val adapter = IngredientsAdapter(emptyList())
ingredientsRecycler.adapter = adapter
lifecycleScope.launchWhenStarted {
detailsViewModel.details.collect {
if (it.details != null) {
adapter.setCocktails(it.details.ingredients)
cocktailName.text = it.details.name
Glide.with(imageCocktail.context)
.load(it.details.thumbDrink)
.into(imageCocktail)
instruction.text = it.details.instruction
serve.text = it.details.serve
}
}
}
Log.d(TAG, "GET id drink = $idDrink")
}
private inline fun <VM : ViewModel> viewModelFactory(crossinline f: () -> VM) =
53
ЧДТУ 242063.017ПЗ
object : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T = f() as T
}
}
Лістинг HomeActivity.kt
package com.example.cocktailmenu.activity
import android.annotation.SuppressLint
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.fragment.app.Fragment
import com.example.cocktailmenu.*
import com.example.cocktailmenu.fragment.CatalogFragment
import com.example.cocktailmenu.fragment.HomeFragment
import com.google.android.material.bottomnavigation.BottomNavigationView
class HomeActivity : AppCompatActivity() {
@SuppressLint("MissingInflatedId")
lateinit var selectedFragment: Fragment
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_home)
val bottomNav = findViewById<BottomNavigationView>(R.id.bottom_nav)
bottomNav.setOnItemSelectedListener(navListener)
supportFragmentManager.beginTransaction().replace(R.id.fragment_container,
HomeFragment())
.commit()
}
54
ЧДТУ 242063.017ПЗ
private val navListener = BottomNavigationView.OnNavigationItemSelectedListener
{
when (it.itemId) {
R.id.home -> {
selectedFragment = HomeFragment()
}
R.id.catalog -> {
selectedFragment = CatalogFragment()
}
}
supportFragmentManager.beginTransaction()
.replace(R.id.fragment_container, selectedFragment).commit()
true
}
}
Лістинг SearchCocktailsActivity.kt
package com.example.cocktailmenu.activity
import android.content.ContentValues
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.SearchView
import android.widget.TextView
import androidx.core.view.isVisible
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
55
ЧДТУ 242063.017ПЗ
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.RecyclerView
import com.example.cocktailmenu.R
import com.example.cocktailmenu.adapter.SearchCocktailsAdapter
import com.example.cocktailmenu.viewModel.SearchCocktailsViewModel
class SearchCocktailsActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_search_cocktails)
val search = findViewById<SearchView>(R.id.search_cocktails)
val recyclerSearch = findViewById<RecyclerView>(R.id.recycler_search)
val textError = findViewById<TextView>(R.id.notFound)
var searchViewModel: SearchCocktailsViewModel
val adapter =
SearchCocktailsAdapter(emptyList(), clickListener = { id ->
launchCocktailDetails(id) })
recyclerSearch.adapter = adapter
searchViewModel = ViewModelProvider(
this,
viewModelFactory { SearchCocktailsViewModel(search.query.toString()) }
)[SearchCocktailsViewModel::class.java]
lifecycleScope.launchWhenStarted {
searchViewModel.search.collect {
if (it.search != null) {
textError.isVisible = false
recyclerSearch.isVisible = true
adapter.setCocktails(it.search)
56
ЧДТУ 242063.017ПЗ
Log.d("adapter set result", it.search.toString())
if (it.search.isEmpty()) {
adapter.setCocktails(emptyList())
recyclerSearch.isVisible = false
textError.isVisible = true
}
}
}
}
search.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String): Boolean {
searchViewModel = SearchCocktailsViewModel(query)
lifecycleScope.launchWhenStarted {
searchViewModel.search.collect {
if (it.search != null) {
textError.isVisible = false
recyclerSearch.isVisible = true
adapter.setCocktails(it.search)
Log.d("adapter set result", it.search.toString())
if (it.search.isEmpty()) {
adapter.setCocktails(emptyList())
recyclerSearch.isVisible = false
textError.isVisible = true
}
}
}
}
return false
}
57
ЧДТУ 242063.017ПЗ
override fun onQueryTextChange(newText: String): Boolean {
searchViewModel = SearchCocktailsViewModel(newText)
lifecycleScope.launchWhenStarted {
searchViewModel.search.collect {
if (it.search != null) {
textError.isVisible = false
recyclerSearch.isVisible = true
adapter.setCocktails(it.search)
Log.d("adapter set result", it.search.toString())
if (it.search.isEmpty()) {
adapter.setCocktails(emptyList())
recyclerSearch.isVisible = false
textError.isVisible = true
}
}
}
}
return false
}
})
}
protected inline fun <VM : ViewModel> viewModelFactory(crossinline f: () -> VM)
=
object : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T = f() as T
}
58
ЧДТУ 242063.017ПЗ
private fun launchCocktailDetails(id: Int) {
Log.d(ContentValues.TAG, "SENT id drink = $id")
val intent = Intent(this@SearchCocktailsActiv ity,
CocktailDetailsActivity::class.java)
intent.putExtra("idDrink", id.toString())
startActivity(intent)
}
}
Лістинг IngredientsAdapter.kt
package com.example.cocktailmenu.adapter
import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.example.cocktailmenu.R
import com.example.cocktailmenu.data.Ingredient
class IngredientsAdapter(
private var mList: List<Ingredient>
) : RecyclerView.Adapter<IngredientsAdapter.ViewHolder>() {
@SuppressLint("NotifyDataSetChanged")
fun setCocktails(ingredients: List<Ingredient>) {
mList = ingredients
notifyDataSetChanged()
59
ЧДТУ 242063.017ПЗ
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.ingredients_recycler_design, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val itemsViewModel = mList[position]
Glide.with(holder.imageIngredient.context)
.load(itemsViewModel.thumb)
.into(holder.imageIngredient)
holder.ingredientName.text = itemsViewModel.name
holder.measure.text = itemsViewModel.measure
}
override fun getItemCount(): Int {
return mList.size
}
class ViewHolder(ItemView: View) : RecyclerView.ViewHolder(ItemView) {
val imageIngredient: ImageView =
itemView.findViewById(R.id.image_ingredient)
val ingredientName: TextView = itemView.findViewById(R.id.ingredient)
60
ЧДТУ 242063.017ПЗ
val measure: TextView = itemView.findViewById(R.id.measure)
}
}
Лістинг SearchCocktailsAdapter.kt
package com.example.cocktailmenu.adapter
import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.example.cocktailmenu.R
import com.example.cocktailmenu.data.SearchDvo
class SearchCocktailsAdapter(
private var mList: List<SearchDvo>,
val clickListener: (idCocktail: Int) -> Unit
) : RecyclerView.Adapter<SearchCocktailsAdapter.ViewHolder>() {
@SuppressLint("NotifyDataSetChanged")
fun setCocktails(search: List<SearchDvo>) {
mList = search
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
61
ЧДТУ 242063.017ПЗ
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.search_recycler_design, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val itemsViewModel = mList[position]
Glide.with(holder.cocktailImage.context)
.load(itemsViewModel.image)
.into(holder.cocktailImage)
holder.cocktailName.text = itemsViewModel.name
holder.itemView.setOnClickListener {
clickListener(itemsViewModel.idDrink.toInt())
}
}
override fun getItemCount(): Int {
return mList.size
}
class ViewHolder(ItemView: View) : RecyclerView.ViewHolder(ItemView) {
val cocktailImage: ImageView = itemView.findViewById(R.id.cocktail_image)
val cocktailName: TextView = itemView.findViewById(R.id.cocktail_name)
}
}
62
ЧДТУ 242063.017ПЗ
Лістинг TabCocktailAdapter.kt
package com.example.cocktailmenu.adapter
import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.example.cocktailmenu.R
import com.example.cocktailmenu.data.Drink
class TabCocktailAdapter(
private var mList: List<Drink>,
val clickListener: (idCocktail: Int) -> Unit
) : RecyclerView.Adapter<TabCocktailAdapter.ViewHolder>() {
@SuppressLint("NotifyDataSetChanged")
fun setCocktails(cocktails: List<Drink>) {
mList = cocktails
notifyDataSetChanged()
}
// create new views
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
// inflates the card_view_design view
// that is used to hold list item
val view = LayoutInflater.from(parent.context)
63
ЧДТУ 242063.017ПЗ
.inflate(R.layout.card_view_design, parent, false)
return ViewHolder(view)
}
// binds the list items to a view
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val itemsViewModel = mList[position]
Glide.with(holder.imageView.context)
.load(itemsViewModel.strDrinkThumb)
.into(holder.imageView)
holder.textView.text = itemsViewModel.strDrink
holder.itemView.setOnClickListener {
clickListener(itemsViewModel.idDrink)
}
}
override fun getItemCount(): Int {
return mList.size
}
class ViewHolder(ItemView: View) : RecyclerView.ViewHolder(ItemView) {
val imageView: ImageView = itemView.findViewById(R.id.cocktail_image)
val textView: TextView = itemView.findViewById(R.id.cocktail_name)
}
}
64
ЧДТУ 242063.017ПЗ
Лістинг ViewPagerAdapter.kt
package com.example.cocktailmenu.adapter
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentPagerAdapter
import com.example.cocktailmenu.AlcoholFragment
import com.example.cocktailmenu.NonAlcoholFragment
class ViewPagerAdapter(fm: FragmentManager, private var tabCount: Int) :
FragmentPagerAdapter(fm) {
override fun getItem(position: Int): Fragment {
return when (position) {
0 -> AlcoholFragment()
1 -> NonAlcoholFragment()
else -> AlcoholFragment()
}
}
override fun getCount(): Int {
return tabCount
}
override fun getPageTitle(position: Int): CharSequence {
return when (position) {
0 -> "Alcohol"
1 -> "Soft"
else -> "Alcohol"
}
65
ЧДТУ 242063.017ПЗ
}
}
Лістинг CocktailsApi.kt
package com.example.cocktailmenu.data
import retrofit2.Response
import retrofit2.http.GET
import retrofit2.http.Query
interface CocktailsApi {
@GET("api/json/v1/1/filter.php?a=Alcoholic")
suspend fun getAlcoholCocktails(): Response<DrinksResponse>
@GET("api/json/v1/1/filter.php?a=Non_Alcoholic")
suspend fun getNonAlcoholCocktails(): Response<DrinksResponse>
@GET("api/json/v1/1/lookup.php")
suspend fun getCocktailDetails(@Query("i") i: String):
Response<DetailsCocktailResponse>
@GET("api/json/v1/1/search.php")
suspend fun getSearchCocktails(@Query("s") search: String):
Response<DetailsCocktailResponse>
}
Лістинг Details.kt
ackage com.example.cocktailmenu.data
data class Details(
val idDrink: String?,
val strDrink: String?,
66
ЧДТУ 242063.017ПЗ
val strDrinkAlternate: String?,
val strTags: String?,
val strVideo: String?,
val strCategory: String?,
val strIBA: String?,
val strAlcoholic: String?,
val strGlass: String?,
val strInstructions: String?,
val strDrinkThumb: String?,
val strIngredient1: String?,
val strIngredient2: String?,
val strIngredient3: String?,
val strIngredient4: String?,
val strIngredient5: String?,
val strIngredient6: String?,
val strIngredient7: String?,
val strIngredient8: String?,
val strIngredient9: String?,
val strIngredient10: String?,
val strIngredient11: String?,
val strIngredient12: String?,
val strIngredient13: String?,
val strIngredient14: String?,
val strIngredient15: String?,
val strMeasure1: String?,
val strMeasure2: String?,
val strMeasure3: String?,
val strMeasure4: String?,
val strMeasure5: String?,
val strMeasure6: String?,
67
ЧДТУ 242063.017ПЗ
val strMeasure7: String?,
val strMeasure8: String?,
val strMeasure9: String?,
val strMeasure10: String?,
val strMeasure11: String?,
val strMeasure12: String?,
val strMeasure13: String?,
val strMeasure14: String?,
val strMeasure15: String?
)
Лістинг DetailsCocktailResponse.kt
package com.example.cocktailmenu.data
data class DetailsCocktailResponse (
val drinks: List<Details>
)
Лістинг DetailsDvo.kt
package com.example.cocktailmenu.data
data class DetailsDvo(
val name: String,
val thumbDrink: String,
val ingredients: List<Ingredient>,
val instruction: String,
val serve: String
)
Лістинг Drink.kt
package com.example.cocktailmenu.data
data class Drink(
68
ЧДТУ 242063.017ПЗ
val strDrink: String,
val strDrinkThumb: String,
val idDrink: Int
)
Лістинг DrinksResponse.kt
package com.example.cocktailmenu.data
data class DrinksResponse(
val drinks : List<Drink>
)
Лістинг Ingredient.kt
package com.example.cocktailmenu.data
data class Ingredient(
val thumb: String,
val name: String,
val measure: String?
)
Лістинг RetrofitHelper.kt
package com.example.cocktailmenu.data
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
object RetrofitHelper {
private var baseUrl = "https://www.thecocktaildb.com/"
fun getInstance(): Retrofit {
return Retrofit.Builder().baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create()).build()
69
ЧДТУ 242063.017ПЗ
}
}
Лістинг SearchDvo.kt
package com.example.cocktailmenu.data
data class SearchDvo(
val name: String,
val category: String,
val image: String,
val idDrink: String
)
Лістинг CatalogFragment.kt
package com.example.cocktailmenu.fragment
import android.content.Intent
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.viewpager.widget.ViewPager
import com.example.cocktailmenu.R
import com.example.cocktailmenu.activity.SearchCocktailsActivity
import com.example.cocktailmenu.adapter.ViewPagerAdapter
import com.google.android.material.tabs.TabLayout
class CatalogFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
70
ЧДТУ 242063.017ПЗ
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_catalog, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val searchView = view.findViewById<View>(R.id.search_cocktails)
val viewPager = view.findViewById<ViewPager>(R.id.view_pager)
val tabCocktails = view.findViewById<TabLayout>(R.id.cocktail_tab)
val adapter = ViewPagerAdapter(parentFragmentManager, tabCocktails.tabCount)
viewPager.adapter = adapter
tabCocktails.setupWithViewPager(viewPager)
searchView.setOnClickListener {
val intent = Intent(it.context, SearchCocktailsActivity::class.java)
startActivity(intent)
}
}
}
Лістинг HomeFragment.kt
package com.example.cocktailmenu.fragment
import android.content.ContentValues.TAG
import android.content.Intent
import android.os.Bundle
71
ЧДТУ 242063.017ПЗ
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.ProgressBar
import android.widget.Toast
import androidx.core.view.isVisible
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.RecyclerView
import com.example.cocktailmenu.*
import com.example.cocktailmenu.activity.CocktailDetailsActivity
import com.example.cocktailmenu.activity.SearchCocktailsActivity
import com.example.cocktailmenu.viewModel.HomeViewModel
class HomeFragment : Fragment() {
private lateinit var homeViewModel: HomeViewModel
private lateinit var adapterAlcohol: ApiCocktailsAdapter
private lateinit var adapterNonAlcohol: ApiCocktailsAdapter
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_home, container, false)
}
72
ЧДТУ 242063.017ПЗ
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
homeViewModel = ViewModelProvider(this)[HomeViewModel::class.java]
val recyclerAlcohol = view.findViewById<RecyclerView>(R.id.recycler_alcohol)
val recyclerNonAlcohol =
view.findViewById<RecyclerView>(R.id.recycler_nonAlcohol)
val pBarAlcohol = view.findViewById<ProgressBar>(R.id.pBarAlcohol)
val pBarNonAlcohol = view.findViewById<ProgressBar>(R.id.pBarNonAlcohol)
val searchView = view.findViewById<View>(R.id.search_cocktails)
adapterAlcohol =
ApiCocktailsAdapter(emptyList(), clickListener = { id ->
launchCocktailDetails(id) })
adapterNonAlcohol =
ApiCocktailsAdapter(emptyList(), clickListener = { id ->
launchCocktailDetails(id) })
recyclerAlcohol.adapter = adapterAlcohol
recyclerNonAlcohol.adapter = adapterNonAlcohol
searchView.setOnClickListener {
val intent = Intent(it.context, SearchCocktailsActivity::class.java)
startActivity(intent)
}
//val pBar = view.findViewById<ProgressBar>(R.id.progressBar)
lifecycleScope.launchWhenStarted {
homeViewModel.cocktail.collect {
when {
!it.cocktails.isNullOrEmpty() -> {
adapterAlcohol.setCocktails(it.cocktails)
pBarAlcohol.isVisible = false
73
ЧДТУ 242063.017ПЗ
}
!it.errorMessage.isNullOrEmpty() -> {
Toast.makeText(
requireContext(), it.errorMessage,
Toast.LENGTH_LONG
).show()
}
}
}
}
lifecycleScope.launchWhenStarted {
homeViewModel.nonAlcoholCocktail.collect {
when {
!it.cocktails.isNullOrEmpty() -> {
adapterNonAlcohol.setCocktails(it.cocktails)
pBarNonAlcohol.isVisible = false
}
!it.errorMessage.isNullOrEmpty() -> {
Toast.makeText(
requireContext(), it.errorMessage,
Toast.LENGTH_LONG
).show()
}
}
}
}
}
private fun launchCocktailDetails(id: Int) {
Log.d(TAG, "SENT id drink = $id")
74
ЧДТУ 242063.017ПЗ
if (activity != null) {
val intent = Intent(context, CocktailDetailsActivity::class.java)
intent.putExtra("idDrink", id.toString())
startActivity(intent)
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == R.id.search_cocktails) {
startActivity(Intent(context, SearchCocktailsActivity::class.java))
}
return super.onOptionsItemSelected(item)
}
}
Лістинг CocktailFragmentState.kt
package com.example.cocktailmenu.model
import com.example.cocktailmenu.data.Drink
data class CocktailFragmentState<T>(
val cocktails: List<Drink>?,
val errorMessage: String?,
val error: Int?,
val loading: Boolean
) {
}
Лістинг CocktailModel.kt
package com.example.cocktailmenu.model
import android.util.Log
75
ЧДТУ 242063.017ПЗ
import com.example.cocktailmenu.data.CocktailsApi
import com.example.cocktailmenu.data.DetailsCocktailResponse
import com.example.cocktailmenu.data.DrinksResponse
import com.example.cocktailmenu.data.RetrofitHelper
import retrofit2.Response
class CocktailModel {
suspend fun getAlcoholCocktail(): Response<DrinksResponse> {
val quotesApi = RetrofitHelper.getInstance()
.create(CocktailsApi::class.java)
val result = quotesApi.getAlcoholCocktails()
Log.d("alcohol: ", result.body().toString())
return result
}
suspend fun getNonAlcoholCocktail(): Response<DrinksResponse> {
val quotesApi = RetrofitHelper.getInstance()
.create(CocktailsApi::class.java)
val result = quotesApi.getNonAlcoholCocktails()
Log.d("non-alcohol: ", result.body().toString())
return result
}
suspend fun getDetailCocktail(i: String): Response<DetailsCocktailResponse> {
76
ЧДТУ 242063.017ПЗ
val quotesApi = RetrofitHelper.getInstance()
.create(CocktailsApi::class.java)
val result = quotesApi.getCocktailDetails(i)
Log.d("id drink", i)
Log.d("details", result.body().toString())
return result
}
suspend fun getSearchCocktails(search: String):
Response<DetailsCocktailResponse> {
val quotesApi = RetrofitHelper.getInstance()
.create(CocktailsApi::class.java)
val result = quotesApi.getSearchCocktails(search)
Log.d("search line", result.body().toString())
return result
}
}
Лістинг DetailsFragmentState.kt
package com.example.cocktailmenu.model
import com.example.cocktailmenu.data.DetailsDvo
data class DetailsFragmentState(
val details: DetailsDvo?,
val errorMessage: String?,
val error: Int?,
val loading: Boolean
)
77
ЧДТУ 242063.017ПЗ
Лістинг SearchFragmentState.kt
package com.example.cocktailmenu.model
import com.example.cocktailmenu.data.SearchDvo
data class SearchFragmentState(
val search: List<SearchDvo>?,
val errorMessage: String?,
val error: Int?,
val loading: Boolean
)
Лістинг AppGlideModule.kt
package com.example.cocktailmenu.modules
import com.bumptech.glide.module.AppGlideModule
class AppGlideModule : AppGlideModule() {
}
Лістинг CocktailDetailsViewModel.kt
package com.example.cocktailmenu.viewModel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.cocktailmenu.data.DetailsCocktailResponse
import com.example.cocktailmenu.data.DetailsDvo
import com.example.cocktailmenu.data.Ingredient
import com.example.cocktailmenu.model.CocktailModel
import com.example.cocktailmenu.model.DetailsFragmentState
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.update
78
ЧДТУ 242063.017ПЗ
import kotlinx.coroutines.launch
import retrofit2.Response
class CocktailDetailsViewModel(id: String) : ViewModel() {
private var cocktailModel = CocktailModel()
val details = MutableStateFlow(
DetailsFragmentState(
null, null, null, true
)
)
init {
fetchCocktailDetails(id)
}
private fun fetchCocktailDetails(id: String) {
viewModelScope.launch {
val response = cocktailModel.getDetailCocktail(id)
processDetails(response)
}
}
private fun processDetails(response: Response<DetailsCocktailResponse>) {
if (response.isSuccessful) {
val ingredients: MutableList<Ingredient> = mutableListOf()
val detailsDto = response.body()!!.drinks.first()
if (detailsDto.strIngredient1 != null) {
79
ЧДТУ 242063.017ПЗ
ingredients.add(
Ingredient(
thumb =
"https://www.thecocktaildb.com/images/ingredients/${detailsDto.strIngredient1}-
Medium.png",
name = detailsDto.strIngredient1,
measure = detailsDto.strMeasure1
)
)
}
if (detailsDto.strIngredient2 != null) {
ingredients.add(
Ingredient(
thumb =
"https://www.thecocktaildb.com/images/ingredients/${detailsDto.strIngredient2}-
Medium.png",
name = detailsDto.strIngredient2,
measure = detailsDto.strMeasure2
)
)
}
if (detailsDto.strIngredient3 != null) {
ingredients.add(
Ingredient(
thumb =
"https://www.thecocktaildb.com/images/ingredients/${detailsDto.strIngredient3}-
Medium.png",
name = detailsDto.strIngredient3,
measure = detailsDto.strMeasure3
)
80
ЧДТУ 242063.017ПЗ
)
}
if (detailsDto.strIngredient4 != null) {
ingredients.add(
Ingredient(
thumb =
"https://www.thecocktaildb.com/images/ingredients/${detailsDto.strIngredient4}-
Medium.png",
name = detailsDto.strIngredient4,
measure = detailsDto.strMeasure4
)
)
}
if (detailsDto.strIngredient5 != null) {
ingredients.add(
Ingredient(
thumb =
"https://www.thecocktaildb.com/images/ingredients/${detailsDto.strIngredient5}-
Medium.png",
name = detailsDto.strIngredient5,
measure = detailsDto.strMeasure5
)
)
}
if (detailsDto.strIngredient6 != null) {
ingredients.add(
Ingredient(
thumb =
"https://www.thecocktaildb.com/images/ingredients/${detailsDto.strIngredient6}-
Medium.png",
81
ЧДТУ 242063.017ПЗ
name = detailsDto.strIngredient6,
measure = detailsDto.strMeasure6
)
)
}
if (detailsDto.strIngredient7 != null) {
ingredients.add(
Ingredient(
thumb =
"https://www.thecocktaildb.com/images/ingredients/${detailsDto.strIngredient7}-
Medium.png",
name = detailsDto.strIngredient7,
measure = detailsDto.strMeasure7
)
)
}
if (detailsDto.strIngredient8 != null) {
ingredients.add(
Ingredient(
thumb =
"https://www.thecocktaildb.com/images/ingredients/${detailsDto.strIngredient8}-
Small.png",
name = detailsDto.strIngredient8,
measure = detailsDto.strMeasure8
)
)
}
if (detailsDto.strIngredient9 != null) {
ingredients.add(
Ingredient(
82
ЧДТУ 242063.017ПЗ
thumb =
"https://www.thecocktaildb.com/images/ingredients/${detailsDto.strIngredient9}-
Medium.png",
name = detailsDto.strIngredient9,
measure = detailsDto.strMeasure9
)
)
}
if (detailsDto.strIngredient10 != null) {
ingredients.add(
Ingredient(
thumb =
"https://www.thecocktaildb.com/images/ingredients/${detailsDto.strIngredient10}-
Medium.png",
name = detailsDto.strIngredient10,
measure = detailsDto.strMeasure10
)
)
}
if (detailsDto.strIngredient11 != null) {
ingredients.add(
Ingredient(
thumb =
"https://www.thecocktaildb.com/images/ingredients/${detailsDto.strIngredient11}-
Medium.png",
name = detailsDto.strIngredient11,
measure = detailsDto.strMeasure11
)
)
}
83
ЧДТУ 242063.017ПЗ
if (detailsDto.strIngredient12 != null) {
ingredients.add(
Ingredient(
thumb =
"https://www.thecocktaildb.com/images/ingredients/${detailsDto.strIngredient12}-
Medium.png",
name = detailsDto.strIngredient12,
measure = detailsDto.strMeasure12
)
)
}
if (detailsDto.strIngredient13 != null) {
ingredients.add(
Ingredient(
thumb =
"https://www.thecocktaildb.com/images/ingredients/${detailsDto.strIngredient13}-
Small.png",
name = detailsDto.strIngredient13,
measure = detailsDto.strMeasure13
)
)
}
if (detailsDto.strIngredient14 != null) {
ingredients.add(
Ingredient(
thumb =
"https://www.thecocktaildb.com/images/ingredients/${detailsDto.strIngredient14}-
Medium.png",
name = detailsDto.strIngredient14,
measure = detailsDto.strMeasure14
84
ЧДТУ 242063.017ПЗ
)
)
}
if (detailsDto.strIngredient15 != null) {
ingredients.add(
Ingredient(
thumb =
"https://www.thecocktaildb.com/images/ingredients/${detailsDto.strIngredient15}-
Mdeium.png",
name = detailsDto.strIngredient15,
measure = detailsDto.strMeasure15
)
)
}
val detailsDvo = DetailsDvo(
name = detailsDto.strDrink!!,
thumbDrink = detailsDto.strDrinkThumb!!,
ingredients = ingredients,
instruction = detailsDto.strInstructions!!,
serve = detailsDto.strGlass!!
)
details.update { it.copy(details = detailsDvo) }
} else {
details.update {
it.copy(
error = response.code(),
errorMessage = response.errorBody().toString()
)
}
85
ЧДТУ 242063.017ПЗ
}
}
}
Лістинг HomeViewModel.kt
package com.example.cocktailmenu.viewModel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.cocktailmenu.data.Drink
import com.example.cocktailmenu.data.DrinksResponse
import com.example.cocktailmenu.model.CocktailFragmentState
import com.example.cocktailmenu.model.CocktailModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import retrofit2.Response
class HomeViewModel : ViewModel() {
private var cocktailModel = CocktailModel()
val cocktail = MutableStateFlow<CocktailFragmentState<List<Drink>>
>(
CocktailFragmentState(
null, null, null, true
)
)
val nonAlcoholCocktail = MutableStateFlow<CocktailFragmentState<List<Drink>>
>(
CocktailFragmentState(
null, null, null, true
)
86
ЧДТУ 242063.017ПЗ
)
init {
fetchAlcoholCocktail()
fetchNonAlcoholCocktail()
}
private fun fetchAlcoholCocktail() {
viewModelScope.launch {
val response = cocktailModel.getAlcoholCocktail()
processCocktails(response)
}
}
private fun fetchNonAlcoholCocktail() {
viewModelScope.launch {
val response = cocktailModel.getNonAlcoholCocktail()
processNonAlcoholCocktails(response)
}
}
private fun processCocktails(response: Response<DrinksResponse>) {
if (response.isSuccessful) {
cocktail.update { it.copy(cocktails = response.body()?.drinks) }
} else {
cocktail.update {
it.copy(
error = response.code(),
errorMessage = response.errorBody().toString()
)
87
ЧДТУ 242063.017ПЗ
}
}
}
private fun processNonAlcoholCocktails(response: Response<DrinksResponse>) {
if (response.isSuccessful) {
nonAlcoholCocktail.update { it.copy(cocktails = response.body()?.drinks) }
} else {
nonAlcoholCocktail.update {
it.copy(
error = response.code(),
errorMessage = response.errorBody().toString()
)
}
}
}
}
Лістинг SearchCocktailsViewModel.kt
package com.example.cocktailmenu.viewModel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.cocktailmenu.data.DetailsCocktailResponse
import com.example.cocktailmenu.data.SearchDvo
import com.example.cocktailmenu.model.CocktailModel
import com.example.cocktailmenu.model.SearchFragmentState
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
88
ЧДТУ 242063.017ПЗ
import retrofit2.Response
class SearchCocktailsViewModel(search: String) : ViewModel() {
private val cocktailModel = CocktailModel()
var search = MutableStateFlow(
SearchFragmentState(
null, null, null, true
)
)
init {
fetchCocktails(search)
}
private fun fetchCocktails(search: String) {
viewModelScope.launch {
val response = cocktailModel.getSearchCocktails(search)
processSearch(response)
}
}
private fun processSearch(response: Response<DetailsCocktailResponse>) {
if (response.isSuccessful) {
val searchResult = response.body()?.drinks
val searchList: MutableList<SearchDvo> = mutableListOf()
searchResult?.forEach {
searchList.add(
SearchDvo(
name = it.strDrink!!,
89
ЧДТУ 242063.017ПЗ
category = it.strCategory!!,
image = it.strDrinkThumb!!,
idDrink = it.idDrink!!
)
)
}
search.update { it.copy(search = searchList) }
} else {
search.update {
it.copy(
search = null,
error = response.code(),
errorMessage = response.errorBody().toString()
)
}
}
}
}
Лістинг AlcoholFragment.kt
package com.example.cocktailmenu
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.ViewModelProvider
class AlcoholFragment : BaseCocktailsFragment() {
90
ЧДТУ 242063.017ПЗ
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_base_cocktails, container, false)
}
override fun initViewModel(): BaseViewModel {
return ViewModelProvider(this)[AlcoholViewModel::class.java]
}
}
Лістинг AlcoholViewModel.kt
package com.example.cocktailmenu
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch
class AlcoholViewModel : BaseViewModel() {
override fun fetchCocktailsData() {
viewModelScope.launch {
val response = cocktailModel.getAlcoholCocktail()
processCocktails(response)
}
}
}
Лістинг ApiCocktailsAdapter,kt
package com.example.cocktailmenu
import android.annotation.SuppressLint
91
ЧДТУ 242063.017ПЗ
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.example.cocktailmenu.data.Drink
class ApiCocktailsAdapter(
private var mList: List<Drink>,
val clickListener: (idCocktail: Int) -> Unit
) : RecyclerView.Adapter<ApiCocktailsAdapter.ViewHolder>() {
@SuppressLint("NotifyDataSetChanged")
fun setCocktails(cocktails: List<Drink>) {
mList = cocktails
notifyDataSetChanged()
}
// create new views
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
// inflates the card_view_design view
// that is used to hold list item
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.recycler_home_design, parent, false)
return ViewHolder(view)
}
92
ЧДТУ 242063.017ПЗ
// binds the list items to a view
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val itemsViewModel = mList[position]
Glide.with(holder.imageView.context)
.load(itemsViewModel.strDrinkThumb)
.into(holder.imageView)
holder.textView.text = itemsViewModel.strDrink
holder.itemView.setOnClickListener {
clickListener(itemsViewModel.idDrink)
}
}
// return the number of the items in the list
override fun getItemCount(): Int {
return mList.size
}
// Holds the views for adding it to image and text
class ViewHolder(ItemView: View) : RecyclerView.ViewHolder(ItemView) {
val imageView: ImageView = itemView.findViewById(R.id.imageview)
val textView: TextView = itemView.findViewById(R.id.textView)
}
}
Лістинг BaseCocktailsFragment.kt
package com.example.cocktailmenu
93
ЧДТУ 242063.017ПЗ
import android.content.ContentValues
import android.content.Intent
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ProgressBar
import android.widget.Toast
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.RecyclerView
import com.example.cocktailmenu.activity.CocktailDetailsActivity
import com.example.cocktailmenu.adapter.TabCocktailAdapter
abstract class BaseCocktailsFragment : Fragment() {
private lateinit var baseViewModel: BaseViewModel
private lateinit var adapter: TabCocktailAdapter
abstract fun initViewModel(): BaseViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_base_cocktails, container, false)
}
94
ЧДТУ 242063.017ПЗ
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
baseViewModel = initViewModel()
val recyclerView = view.findViewById<RecyclerView>(R.id.recyclerview)
adapter =
TabCocktailAdapter(emptyList(), clickListener = { id ->
launchCocktailDetails(id) })
recyclerView.adapter = adapter
val pBar = view.findViewById<ProgressBar>(R.id.progressBar)
lifecycleScope.launchWhenStarted {
baseViewModel.cocktail.collect {
when {
!it.cocktails.isNullOrEmpty() -> {
adapter.setCocktails(it.cocktails)
pBar.isVisible = false
}
!it.errorMessage.isNullOrEmpty() -> {
Toast.makeText(
requireContext(), it.errorMessage,
Toast.LENGTH_LONG
).show()
}
}
}
}
}
private fun launchCocktailDetails(id: Int) {
Log.d(ContentValues.TAG, "SENT id drink = $id")
95
ЧДТУ 242063.017ПЗ
if (activity != null) {
val intent = Intent(context, CocktailDetailsActivity::class.java)
intent.putExtra("idDrink", id.toString())
startActivity(intent)
}
}
}
Лістинг BaseViewModel.kt
package com.example.cocktailmenu
import androidx.lifecycle.ViewModel
import com.example.cocktailmenu.data.Drink
import com.example.cocktailmenu.data.DrinksResponse
import com.example.cocktailmenu.model.CocktailFragmentState
import com.example.cocktailmenu.model.CocktailModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.update
import retrofit2.Response
abstract class BaseViewModel : ViewModel() {
protected var cocktailModel = CocktailModel()
val cocktail = MutableStateFlow<CocktailFragmentState<List<Drink>>
>(
CocktailFragmentState(
null, null, null, true
)
)
init {
fetchCocktailsData()
96
ЧДТУ 242063.017ПЗ
}
abstract fun fetchCocktailsData()
fun processCocktails(response: Response<DrinksResponse>){
if(response.isSuccessful){
cocktail.update { it.copy(cocktails = response.body()?.drinks) }
}else{
cocktail.update { it.copy(error = response.code(),
errorMessage = response.errorBody().toString()) }
}
}
}
Лістинг NonAlcoholFragment.kt
package com.example.cocktailmenu
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.ViewModelProvider
class NonAlcoholFragment : BaseCocktailsFragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_base_cocktails, container, false)
97
ЧДТУ 242063.017ПЗ
}
override fun initViewModel(): BaseViewModel {
return ViewModelProvider(this)[NonAlcoholViewModel::class.java]
}
}
Лістинг NonAlcoholViewModel.kt
package com.example.cocktailmenu
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch
class NonAlcoholViewModel : BaseViewModel() {
override fun fetchCocktailsData() {
viewModelScope.launch {
val response = cocktailModel.getNonAlcoholCocktail()
processCocktails(response)
}
}
}
98
ЧДТУ 242063.017ПЗ
ДОДАТОК В
Проектування інформаційної системи каталогу напоїв
Інструкція користувачеві
482.ЧДТУ. 242063 34 01
Листів 2
Розробник ________________ Шраменко В.М.
2024
99
ЧДТУ 242063.017ПЗ
Для початку роботи з мобільним додатком необхідно:
1. Мати пристрій з операційною системою Android не нижче версії 5.0.
2. Встановити додаток через файл з розширенням .apk.
3. Відкрити додаток.
На графічному інтерфейсі мобільного додатку буде відображено категорійно
алкогольні та безалкогольні напої, які можна гортати та одразу обирати потрібний
напій для перегляду рецепту його приготування.
Для прискорення пошуку потрібного напою можна скористатись пошуковою
системою. При натиску на поле «Search» відкривається вікно, в якому можна
ввести потрібний напій та знайти його швидше.
Знизу розташоване меню з вибором головної сторінки або сторінки каталогу,
в якому також розподілені напої по категоріям «алкогольні» та «безалкогольні».
Через нього також можна обрати потрібний для перегляду рецепту напій.
100
ЧДТУ 242063.017ПЗ
ДОДАТОК Г
ЗАТВЕРДЖЕНО:
Зав. кафедрою ПЗАС, професор
_________________ Голуб С.В.
„____” ______________ 2024 р.
Проектування інформаційної системи каталогу напоїв
Графічні матеріали
482. ЧДТУ 242063.034 90 01
Листів 8
Розробник ________________ Шраменко В.М.
Керівник ________________ Куницька С.Ю.
2024
101
ЧДТУ 242063.017ПЗ
Рисунок 1 – Слайд 1 «Титульна сторінка»
Рисунок 2 – Слайд 2 «Вступ»
102
ЧДТУ 242063.017ПЗ
Рисунок 3 – Слайд 3 «Первинні та детальні вимоги»
Рисунок 4 – Слайд 4 «Діаграма прецедентів»
103
ЧДТУ 242063.017ПЗ
Рисунок 5 – Слайд 5 «Проектування логічної структури»
Рисунок 6 – Слайд 6 «Архітектурне проектування»
104
ЧДТУ 242063.017ПЗ
Рисунок 7 – Слайд 7 «Моделювання поведінки системи»
Рисунок 8 – Слайд 8 «Діаграма скінченного автомату інтерфейсу»
105
ЧДТУ 242063.017ПЗ
Рисунок 9 – Слайд 9 «Структурна та функціональна схема»
Рисунок 10 – Слайд 10 «API»
106
ЧДТУ 242063.017ПЗ
Рисунок 11 – Слайд 11 «Інтерфейс користувача»
Рисунок 12 – Слайд 12 «Тестування»
107