+ All Categories
Home > Documents > ДИПЛОМНА РОБОТА - ela.kpi.ua

ДИПЛОМНА РОБОТА - ela.kpi.ua

Date post: 28-Nov-2021
Category:
Upload: others
View: 19 times
Download: 0 times
Share this document with a friend
64
НАЦІОНАЛЬНИЙ ТЕХНІЧНИЙ УНІВЕРСИТЕТ УКРАЇНИ “КИЇВСЬКИЙ ПОЛІТЕХНІЧНИЙ ІНСТИТУТ ІМЕНІ ІГОРЯ СІКОРСЬКОГО” _______ ___________________ Теплоенергетичний факультет _______________________ Кафедра автоматизації проектування енергетичних процесів і систем До захисту допущено Завідувач кафедри __________ О.В.Коваль (підпис) (ініціали, прізвище) “___”_____________2019 р. ДИПЛОМНА РОБОТА на здобуття ступеня бакалавра з напряму підготовки 6.050103 “Програмна інженерія’’ на тему: Мобідьний застосунок RozkladKPI для платформ iOS та Android Виконав: студент 4 -курсу, групи ТІ-51 - Можайський Михайло Валерійович д _________ (прізвище, ім’я, по батькові) (підпис) Керівник доцент, к.т.н. Ходаківський Олександр Володимирович_ _________ (посада, вчене звання, науковий ступінь, прізвище та ініціали) (підпис) Рецензент ____ _________ (посада, вчене звання, науковий ступінь, прізвище та ініціали) (підпис) Засвідчую, що у цій дипломній роботі немає запозичень з праць інших авторів без відповідних посилань. Студент _____________ (підпис) Київ – 2019
Transcript
Page 1: ДИПЛОМНА РОБОТА - ela.kpi.ua

НАЦІОНАЛЬНИЙ ТЕХНІЧНИЙ УНІВЕРСИТЕТ УКРАЇНИ

“КИЇВСЬКИЙ ПОЛІТЕХНІЧНИЙ ІНСТИТУТ ІМЕНІ ІГОРЯ СІКОРСЬКОГО”

_______ ___________________ Теплоенергетичний факультет _______________________

Кафедра автоматизації проектування енергетичних процесів і систем

До захисту допущено Завідувач кафедри __________ О.В.Коваль (підпис) (ініціали, прізвище)

“___”_____________2019 р.

ДИПЛОМНА РОБОТА на здобуття ступеня бакалавра

з напряму підготовки

6.050103 “Програмна інженерія’’

на тему: Мобідьний застосунок RozkladKPI для платформ iOS та Android Виконав: студент 4 -курсу, групи ТІ-51 - Можайський Михайло Валерійович д _________ (прізвище, ім’я, по батькові) (підпис)

Керівник доцент, к.т.н. Ходаківський Олександр Володимирович_ _________ (посада, вчене звання, науковий ступінь, прізвище та ініціали) (підпис) Рецензент ____ _________ (посада, вчене звання, науковий ступінь, прізвище та ініціали) (підпис)

Засвідчую, що у цій дипломній роботі немає запозичень з праць інших авторів без відповідних посилань. Студент _____________

(підпис)

Київ – 2019

Page 2: ДИПЛОМНА РОБОТА - ela.kpi.ua

2

Національний технічний університет України “Київський політехнічний інститут імені Ігоря Сікорського”

Факультет теплоенергетичний Кафедра автоматизації проектування енергетичних процесів і систем Рівень вищої освіти перший рівень Напрям підготовки 6.050103 “Програмна інженерія’’

ЗАТВЕРДЖУЮ Завідувач кафедри _______ О.В. Коваль (підпис)

”___”___________2019 р.

ЗАВДАННЯ

на дипломну роботу студенту Можайський Михайло Валерійович___ п

(прізвище, ім’я, по батькові)

1. Тема роботи “Мобідьний застосунок RozkladKPI для платформ iOS та Android” керівник роботи доцент, к.т.н. у Ходаківський Олександр Володимирович п

(прізвище, ім’я, по батькові науковий ступінь, вчене звання)

затверджена наказом вищого навчального закладу від ” ” 201 р. № .

2. Строк подання студентом роботи 201 р. 3. Вихідні дані до роботи персональний комп’ютер під керуванням операційної системи Microsoft Windows, мова програмування MATLAB, мова програмування C#. 4. Зміст розрахунково-пояснювальної записки (перелік питань, які потрібно розробити) проаналізувати існуючі програмні рішення та можливі засоби реалізації взаємодії, обґрунтувати обрані програмні застосунки та шляхи розробки програмних додатків, розробити програмне забезпечення, розробити користувацький інтерфейс, зробити висновки за результатами роботи_____________________________________ 5. Перелік ілюстраційного матеріалу (з точним зазначенням обов’язкових креслень) 1. Моделювання гідроакустичних процесів 2. Гідроакустичний процес. Формула Вільсона. 3.Підключення бібліотеки MATLAB до C# проекту для реалізації взаємодії. 4.Підключення бібліотеки C# до MATLAB проекту для реалізації взаємодії. 5.Схема взаємодії C# з MATLAB. 6.Схема взаємодії MATLAB з C#. 7.Апробація результатів роботи__________________________________________________________________ 6. Публікації: ХVІ Міжнародна науково-практична конференція аспірантів, магістрантів і студентів “Сучасні проблеми наукового забезпечення енергетики”, м. Київ, КПІ ім. Ігоря Сікорського, 24-27 квітня 2018 року, ХХІІІ Міжнародна науково–практична конференція молодих вчених, аспірантів та студентів “Європейська інтеграція України в контексті освітньої та молодіжної політики”, м. Київ, КиМУ, 18 квітня 2018 року, V науково-практична дистанційна конференція молодих вчених і фахівців з розробки програмного забезпечення “Сучасні аспекти розробки програмного забезпечення”,м.

Page 3: ДИПЛОМНА РОБОТА - ela.kpi.ua

3

Київ, КПІ ім. Ігоря Сікорського, 15 травня 2018 року. Дата видачі завдання ” ” 201 р.

КАЛЕНДАРНИЙ ПЛАН

№ з/п

Назва етапів виконання дипломної роботи

Термін виконання етапів роботи

Примітки

1. Вивчення та аналіз задачі 2. Розробка архітектури та загальної

структури системи

3. Розробка структур окремих підсистем 4. Підготовка матеріалів 5. Програмна реалізація системи 6. Захист програмного продукту 7. Оформлення пояснювальної записки 8. Передзахист 9. Захист

Студент ___________ Можайський М.В. д

(підпис) (прізвище та ініціали)

Керівник роботи ___________ Ходаківський О.В. а (підпис) (прізвище та ініціали)

Page 4: ДИПЛОМНА РОБОТА - ela.kpi.ua

4

АНОТАЦІЯ

Мета роботи – дослідження технології Kotlin native для розробки

крос-платформних мобільних додатків для платформ Android та iOS. При

проведенні дослідження створити два мобільних застосунки, що будуть

використовувати спільну бізнес-логіку, написану використовуючи

технологію на Kotlin native.

Записка містить 50 сторінок, 10 рисунків і 18 посилань.

Ключові слова: Android, iOS, Kotlin, Kotlin native, React native,

Xamarin, Clean architecture.

ABSTRACT The purpose of the work is to research Kotlin native technology as a

instrument to development cross-platform mobile application for Android and

iOS platforms. During research work develop two mobile application which was

used common business logic. Common business logic use Kotlin native.

The note contains 50 pages, 10 figures and 18 links.

Keywords: Android, iOS, Kotlin, Kotlin native, React native, Xamarin,

Clean architecture.

Page 5: ДИПЛОМНА РОБОТА - ela.kpi.ua

5

ЗМІСТ ПЕРЕЛІК УМОВНИХ ПОЗНАЧЕНЬ, СКОРОЧЕНЬ І ТЕРМІНІВ ........................... 6

ВСТУП ..................................................................................................................................... 7 2 ЗАДАЧА СТВОРЕННЯ МОБІЛЬНИХ ЗАСТОСУНКІВ ...................................... 9

1.1 Платформи Android та iOS ............................................................................................. 10 1.2 Причини виникнення крос-платформних мобільних застосунків ............................... 13

2 АНАЛІЗ МОБІЛЬНОЇ РОЗРОБКИ ТА РОЛЬ КРОС-ПЛАТФОРМНИХ ТЕХНОЛОГІЙ У НІЙ ........................................................................................................ 16

2.1 Аналіз існуючих крос-платформних технологій ............................................................... 17 2.2 Огляд архітектури мобільного застосунку ......................................................................... 19 Висновки до розділу 2 ................................................................................................................... 29

3 Аналіз технології Kotlin Native та її ефективність в розробці мобільних застосунків ............................................................................................................................ 30

3.1 LLVM компілятор ................................................................................................................... 31 3.2 Розробка специфічних для платформи модулів ................................................................ 33 3.3 Дослідження ефективності розробки ................................................................................... 36 3.4 Недоліки технології Kotlin native ......................................................................................... 37 Висновки до розділу 3 ................................................................................................................... 38

4 ОГЛЯД ПРОГРАМНОЇ РЕАЛІЗАЦІЇ ДОДАТКУ «РОЗКЛАД» ........................ 39 4.1 Створення Use case об’єкта ............................................................................................ 39 4.2 Приклад реалізації репозиторія .................................................................................... 40 4.3 Реалізації LessonDataStore ..................................................................................................... 41

5 ВИКОРИСТАННЯ РОЗРОБЛЕНОГО ПРОГРАМНОГО ПРОДУКТУ ................ 43

6 ЗАСОБИ РЕАЛІЗАЦІЇ .................................................................................................... 45 6.1 Android studio ........................................................................................................................... 45 6.2 Kotlin .......................................................................................................................................... 46 6.3 Gradle ......................................................................................................................................... 48

ВИСНОВКИ ......................................................................................................................... 50

СПИСОК ВИКОРИСТАНИХ ДЖЕРЕЛ ........................................................................ 51 ДОДАТОК А ......................................................................................................................... 53

ДОДАТОК Б ......................................................................................................................... 54 ДОДАТОК В ......................................................................................................................... 64

Page 6: ДИПЛОМНА РОБОТА - ela.kpi.ua

6

ПЕРЕЛІК УМОВНИХ ПОЗНАЧЕНЬ,

СКОРОЧЕНЬ І ТЕРМІНІВ

IDE — Integrated Development Environment.

XML — Extensible Markup Language.

COM — Component Object Model.

OLE — Object Linking and Embedding.

DDE — Dynamic Data Exchange.

CORBA — Common Object Request Broker Architecture.

API — Application Programming Interface.

GUI — Graphical User Interface.

ЕОМ — Електронна Обчислювальна Машина.

HCI — Human-Computer Interaction.

IPC — Inter-Process Communication.

RPC — Remote Procedure Call.

CLR — Common Language Runtime.

DLL — Dynamic Link Library.

CMS — Content Management System.

MFC — Microsoft Foundation Classes.

TCP — Transmission Control Protocol.

Page 7: ДИПЛОМНА РОБОТА - ela.kpi.ua

7

ВСТУП

Популярність мобільних додатків виникла через глибоку взаємодію з

користувачем та можливістю покрити майже всі його інформаційні

потреби. За рахунок своєї гнучкості, мобільні додатки замінили собою

цілий ряд пристроїв, що були необхідними для користувача та колись

здавалися незамінними, такі як навігатор, календар, блокнот, радіо

приймач, фотокамера, відеокамера.

Архітектура надзвичайно важливий аспект в створенні програмного

забезпечення. Вона впливає на швидкість розробки, можливість підтримки,

тестування, гнучкість та стабільність програмного продукту.

На сьогодні в мобільній розробці існує парадигма «Чистої

архітектури» - набір рекомендацій для написання програми, що увібрав у

себе всі відомі рекомендації, такі як шаблони проектування та SOLID

принцип. Ця парадигма забезпечує написання чистого та стабільного

програмного коду, який легко тестувати, розширювати та підтримувати.

Кросплатформність – властивість програмного продукту працювати

на кількох платформах (операційних системах) одночасно.

Кросплатформність дозволяє суттєво скоротити час та кошти на розробку

ПЗ. Однак, це додає складності програмного продукту та впливає на його

ефективність.

Kotlin native має кардинально інший підхід до створення та

впровадження крос-платформного системи. На відміну від Xamarin та React

native, ця технологія не має можливостей до написання спільного

користувацького інтерфейсу, що, в свою чергу, позбавляє від більшості

системних залежностей, які вимагають специфічні платформні драйвери

або створення додаткового шару виконання.

Основна ідея – створення спільної логіки, яка мати велику швидкодію

за рахунок компіляції в бінарний код. Отже, розробники створюють лише

Page 8: ДИПЛОМНА РОБОТА - ela.kpi.ua

8

спільну логіку, яка буде використовуватись інтерфейсом, написаним на

офіційних технологіях, таких як Java або Kotlin для Android та Objective-C

або Swift для iOS.

Page 9: ДИПЛОМНА РОБОТА - ela.kpi.ua

9

2 ЗАДАЧА СТВОРЕННЯ МОБІЛЬНИХ

ЗАСТОСУНКІВ

Мобільний застосунок – це вид програмного забезпечення, що

виконується на мобільних пристроях, таких як смартфон або планшет. Цей

напрям існує і розвивається за рахунок ряду переваг порівняно із звичайним

сайтом. За останні роки такий вид програмного продукту набув великої

популярності.

Багато мобільних застосунків вже встановленні на мобільних

пристроях, а деякі з них користувач може власноруч завантажити зі

спеціалізованих онлайн магазинів. Найпопулярніші онлайн магазини

мобільних застосунків – AppStore та Google Play. Багато з програм, що

представленні у цих магазинах, є платними. Через потенційний заробіток

на продажі мобільних застосунків, а також можливості розміщення

реклами, з якої можуть отримувати прибуток розробники застосунків,

навколо цього напряму програмного забезпечення з роками була створена

ціла бізнес сфера [1].

Також розробка мобільних застосунків стала однією з найбільш

затребуваних галузей в програмуванні та об’єднала тисячі інженерів, які

працюють над комерційними та некомерційними (мають відкритий

програмний код та можуть використовуватись безкоштовно) проектами.

Популярність мобільних додатків виникла через глибоку взаємодію з

користувачем та можливістю покрити майже всі його інформаційні

потреби. За рахунок своєї гнучкості, мобільні додатки замінили собою

цілий ряд пристроїв, що були необхідними для користувача та колись

здавалися незамінними, такі як навігатор, календар, блокнот, радіо

приймач, фотокамера, відеокамера.

Page 10: ДИПЛОМНА РОБОТА - ela.kpi.ua

10

Найбільш поширені мобільні платформи – Android та iOS, які

покривають більше ніж дев’яносто відсотків мобільного ринку.

Існують такі види мобільних додатків:

- організаційні – різноманітні календарі та записники, що

дозволяють користувачу швидко зберігати та обробляти

інформацію та проводити моніторинг свого часу;

- розважальні – застосунки, що забезпечують дозвілля користувача,

таке як перегляд фільмів або відеороликів, прослуховування

музики або радіо, тощо;

- ігрові – одні з найбільш популярних серед користувачів додатків,

що використовуються для розваг;

- спеціалізовані – професійні додатки, що використовуються для

навчання та роботи.

1.1 Платформи Android та iOS

Мобільна платформа – це ціла операційна система, що потребує

великої кількості інженерних ресурсів для її підтримки та вдосконалення.

Також для успішності мобільної операційної системи потрібна глибока

різноманітність програмних продуктів, що можуть використовуватись на

тій чи іншій платформі [1]. Для цього окрім самої системи потрібно

розвивати програмні засоби-інструменти для розробки ПЗ, що може

використовуватись у цих мобільний платформах. Цей процес вимагає

колосальних фінансових вкладень. Тому виготовлення та підтримку ОС

може собі дозволити тільки компанія з високими фінансовими активами.

Сьогодні на ринку існує дві такі компанії, що близько десяти років

тому зайняли на ринку ПЗ нішу мобільний операційних систем. Це – Apple

та Google – мільярдні корпорації з десятками тисяч інженерів і рядах своїх

Page 11: ДИПЛОМНА РОБОТА - ela.kpi.ua

11

працівників. Кожна з них представила свою операційну систему. Apple

створила iOS, що працює ексклюзивно на смартфонах цієї ж компанії, та

Google – Android, яка є відкритою системою, що працює на смартфонах

десятка різноманітних компаній.

Android базується на ядрі Linux та підтримується альянсом

розробників ПЗ із відкритим програмним кодом Open Handset Alliance.

Хоча основою Android-системи є ядро Linux, він залишається осторонь

розвитку Linux-спільноти та Linux-інфраструктури в цілому. Базою для цієї

операційної системи є Dalvik віртуальна машина Java, і все програмне

забезпечення системи опирається на цю реалізацію Java Virtual Machine [2].

ОС Android за рахунок своєї відкритості займає набагато більшу долю

ринку мобільних пристроїв. Окрім Google, смартфони з Android на борту

випускають Samsung, Moto, Huawei, One Plus та ще тисячі менш відомих

компаній. 84 відсотка усіх смартфонів, що продаються у світі за один рік,

використовують Android як операційну систему.

Історія Android сягає 2003 року, коли Енді Рубен, що колись заснував

компанію Danger, Річард Майнер (засновник Wildfire Communication) та

Нік Сірс (на той час віце-президент компанії T-Mobile) заснували компанію

Android, Inc для створення досконалої операційною системи для цифрових

фотоапаратів, однак вони відразу зрозуміли, що ринок був занадто малим, і

вони об’єднали свої зусилля для створення системи для смартфонів. На той

час на ринку були представленні такі гравці мобільної індустрії Symbian від

Nokia та Windows Phone, кожна з них мала свої певні недоліки. Основною

проблемою Symbian була різноманітність версій (близько 70), кожна з яких

не могла працювати між собою, це відштовхувало сторонніх розробників

від розробки ПЗ для цієї платформи, так як кожну програму потрібно було

адаптувати під кожну з версій, що мало мінімальну ефективність. Windows

Phone мала складні програмні інструменти для розробки ПЗ для цієї

платформи, що також відштовхувало розробників. А через відсутність

Page 12: ДИПЛОМНА РОБОТА - ela.kpi.ua

12

різноманітного ПЗ ці платформи не могли задовільнити користувачів, що

призвело до їх занепаду та виходу з ринку мобільних операційних систем.

У 2005 році компанію Android, Inc була куплена компанією Google, яка

надала новий поштовх та ресурси для розвитку ОС. Сьогодні ОС Android

налічує 14 версій, остання з яких Android 9.0 Pie, а найстарша актуальна –

Android 5.0 Lollipop.

Платформа Android легко пристосовується до використання бібліотек

двовимірної та тривимірної реальності на основі OpenGL ES 1.0

специфікацій, що є традиційними для мобільний пристроїв. Основною

базою даних, що підтримується системою є SQLite – реляційна база даних

на основі SQL. Також система підтримує більшість актуальних технологій

зв’язку, у тому числі: GSM, Bluetooth, EDGE, 3G, LTE та WiFi. Android

підтримує такі формати для аудіо/відео даних та зображень: MPEG-4,

H.264, MP3, та AAC, AMR, JPG, PNG, GIF. Система надає підтримку усім

можливим датчикам та приладам, що встановлюють у сучасні смартфони, а

саме: відеокамери, фотоапарати, дотикові екрани, GPS, компаси,

акселерометри, та прискорювачі 3D графіки. Офіційним середовищем

розробки є Android Studio, створене на базі Intellij IDEA. Містить емулятор,

засоби налагодження, профілювання пам'яті та швидкодії. Також доступні

плагіни для Intellij IDEA, Eclipse та NetBeans. Android доступний для різних

апаратних платформ, таких як ARM, MIPS, x86.

Платформа iOS – це операційна система від компанії Apple. Спочатку

була розроблена для смартфону iPhone, що є основним мобільним

пристроєм, що випускається компанією [3]. Згодом система була

вдосконалена для використання планшетом iPad. Особливістю системи,

порівняно з Android, є її закритість. Це проявляться не лише у

розповсюдженні системи (вона доступна лише для смартфонів компанії

Apple і не може використовуватись більше ніяким виробником), але і у

повсякденному користуванні, а саме – користувач не може встановлювати

Page 13: ДИПЛОМНА РОБОТА - ela.kpi.ua

13

сторонні застосунки, тобто ті, що не були офіційно опубліковані у онлайн

магазині застосунків AppStore. iOS є похідною від системи OS X, що

використовується у комп’ютерах компанії. OS X є UNIX-подібною

системою, отже iOS за природою свого походження також є такою. Станом

на 2018 рік, iOS становив близько 15 відсотків від усього світового ринку

смартфонів.

Кожна з цим операційних систем мають однакові способи взаємодії з

користувачами. Тому розроблені мобільні застосунки на кожній з платформ

мають схожий вид, логіку та набір функцій.

1.2 Причини виникнення крос-платформних мобільних застосунків

Кросплатформність – властивість програмного продукту працювати

на кількох платформах (операційних системах) одночасно.

Кросплатформність дозволяє суттєво скоротити час та кошти на розробку

ПЗ. Однак, це додає складності програмного продукту та впливає на його

ефективність.

Існує декілька видів кросплатформності, а саме кросплатформність

мов програмування, росплатформність на рівні середовища виконання та

росплатформність на апаратному рівні.

Кросплатформність на рівні мов програмування досягається шляхом

забезпечення незалежності програмного коду від платформи.

Багатоплатформними є більшість сучасних високорівневих мов

програмування, для яких реалізовані транслятори, що можуть виконуватись

на різних платформах. За рахунок цього єдиний код може компілюватись з

особливостями платформи за рахунок властивостей компілятора. C, Java,

С++ та Pascal — кросплатформні мови на рівні компіляції, тобто для цих

мов є компілятори під різні платформи. Кросплатформність на рівні

Page 14: ДИПЛОМНА РОБОТА - ela.kpi.ua

14

редакторів зв’язків досягається реалізацією для різних платформ

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

інтерфейс, в тому числі — стандартизованих бібліотек. Зокрема,

стандартизовані багато бібліотек мови Сі. Існує також велика кількість

нестандартних кросплатформних бібліотек: Qt, GTK+, FLTK, STL, Boost,

OpenGL, SDL, OpenAL, OpenCL.

Кросплатформність на рівні середовищ виконання забезпечується

реалізацією в цих середовищах можливостей, необхідних програмам

незалежно від платформи. Декларований набір таких можливостей

прийнято називати «контрактом» — обов'язком який покладається на

середовище, щоб забезпечити виконання програми. Ці обов'язки

реалізуються через інтерпретатор, файлові потоки, системні виклики,

протоколи, віртуальну машину тощо. Java і C# — кросплатформні мови на

рівні виконання, тобто їх виконавчі файли можна запускати на різних

платформах без попередньої перекомпіляції. PHP, Python і Ruby —

кросплатформні інтерпретовані мови, їх інтерпретатори існують для

багатьох платформ.

Крос-платформність на апаратному рівні досягається реалізацією

однакових машинних команд та форматом їх представлення, систем

переривань, механізмів адресації пам'яті, регістрів тощо. Може досягатись

шляхом віртуалізації відповідних ресурсів та механізмів.

Основна причина виникнення кросплатформності проста –

ефективність зі сторони бізнесу. Потенційні користувачі майбутньої

системи використовують різні ОС, і щоб повністю покрити ринок, продукт

повинен працювати на усіх найбільш популярних ОС [4]. Можливість

працювати на усіх платформах, що вибрав користувач – це перший крок до

того, щоб задовільнити його потреби. Розробка одного програмного

продукту, що може компілюватись на всі платформи набагато дешевше, ніж

розробка ПЗ під кожну платформу окремо.

Page 15: ДИПЛОМНА РОБОТА - ela.kpi.ua

15

Ще одним фактором для такого підходу стала економія інженерних

ресурсів. Для розробки під кожну платформу існують свої програмні

інструменти та мови програмування, для роботи з якими потрібні

специфічні знання та досвід [4]. Більшість з них відрізняються кардинально,

тому потрібно наймати команду із спеціалістів для кожної платформи. А це

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

фінансування команди.

У розробці мобільних застосунків крос-платформний підхід

надзвичайно популярний. Доля розробки крос-платформних застосунків на

мобільному ранку сягає двадцяти відсотків. Існує велика кількість

програмних засобів для розробки таких застосунків, а саме QT, Xamarin,

React Native та інші.

З розвитком архітектурних підходів та сторонніх бібліотек, які мають

спільну логіку, структуру та шаблони поведінки, при розробці мобільних

застосунків все більше бізнес логіки не залежить від платформної

реалізації. Цю незалежну логіку можна легко виносити у спільні модулі та

поширювати між реалізаціями програм, створених під певну платформу.

Page 16: ДИПЛОМНА РОБОТА - ela.kpi.ua

16

2 АНАЛІЗ МОБІЛЬНОЇ РОЗРОБКИ ТА РОЛЬ

КРОС-ПЛАТФОРМНИХ ТЕХНОЛОГІЙ У НІЙ

Теоретично мобільні застосунки для усіх актуальних платформ (iOS

та Android) схожі. Проте кожна з цих платформ була створена різними

компаніями, що мають різне бачення ринку мобільних продуктів, різний

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

Через цю базову відмінність програмна реалізація кожного з компонентів

системи, що здається однаковим на кожній з платформ, є кардинально різна

з технічної точки зору. Відповідно, відмінність в реалізації спричиняє

різноманітність в створенні ПЗ для кожної з систем.

Операційна система Android працює на Dalvik Virtual Machine, яка

представляє з себе спрощену версію базової Java Virtual Machine. Для

розробки ПЗ під яку використовується мови програмування, що здатні

компілюватись в байт-код, який у свою чергу і запускається на JVM [5].

Найпопулярнішою мовою програмування, що базується на JVM є

Java, яка, до недавнього часу, і була основною мовою програмування для

розробки мобільних застосунків для Android. У 2015 році Google

представила підтримку Kotlin – молодої мови програмування, що

розробляється компанією JetBrains. Kotlin увібрав у себе усі сучасні ідеї для

розробки ПЗ, а саме функціональний, процедурний та об’єкто-орієнтовний

стилі програмування. Також Kotlin має зручний та лаконічний C-подібний

синтаксис та багату стандартну бібліотеку.

Також разом Android ОС поставляється Android SDK – набір

програмних інструментів для розробки ПЗ під Android платформу.

iOS від Apple використовує Objective-C та Swift для створення ПЗ.

Код цих мов компілюється в мову програмування C, а далі в асемблерний

Page 17: ДИПЛОМНА РОБОТА - ela.kpi.ua

17

код, що виконується процесором мобільного пристрою [5]. Це надає певну

незалежність від віртуальної машини та вищу продуктивність програм, за

рахунок відсутності проміжного рівня між системою та програмним кодом.

Основна ідея створення крос-платформних мобільний застосунків

полягає в написанні спільного коду, що буде компілюватись в мову

програмування, що вже підтримується платформою, а саме Java для Android

та Objective-C або Swift для iOS.

2.1 Аналіз існуючих крос-платформних технологій

Xamarin – набір інструментів для розробки крос-платформних

мобільних додатків та програм для портативних комп’ютерів на

операційних системах Windows та MacOS. Компанія Xamarin почала свій

шлях у 2011 році як стартап. Однак через декілька років свого існування

була викуплена компанією Microsoft. Xamarin займається розробкою та

підтримкою Mono та інструментів розробки за допомогою мови

програмування C# з використанням технологій .NET [6].

Хоча це достатньо популярна технологія, що дозволяє писати

справжній крос-платформний програмний продукт з мінімальною

кількістю коду, що потребує платформної спеціалізації, Xamarin має цілий

ряд вагомих недоліків, а саме:

- повільна робота – за рахунок того, що для запуску C# коду поверх

ОС потрібно додатковий рівень абстракції. Створюється ефект

програми в програмі;

- великий розмір застосунку – рівні за змістом мобільні застосунки,

одні з який написані на Xamarin, інші - використовуючи стандартні

технології, що не підтримують кросплатформність, будуть

відрізнятись у рази за розміром. Звичайно, не у користь Xamarin;

Page 18: ДИПЛОМНА РОБОТА - ela.kpi.ua

18

- слабка підтримка – недостатня кількість оновлень системи, що

включали б підтримку нових апаратних функцій кожної з

платформ. Незважаючи на великий потенціал Xamarin та Microsoft

за рахунок великої різноманітності підтримуваних платформ не

встигає за їх оновленнями;

- потреба в C#, Android та iOS спеціалістах одночасно – хоча

Xamarin позиціонує себе як повністю крос-платформна технологія,

під час процесу розробки виникає необхідність написання

специфічних для кожної платформи модулів. Тому для

повноцінної роботи команди розробників потрібні і C# інженери, і

експерти в мобільній розробці під Android та iOS [6].

Xamarin займає близько 30 відсотків ринку крос-платформних

мобільних застосунків.

React Native - це фреймворк JavaScript для написання мобільних

додатків для iOS і Android. Вона базується на бібліотеці JavaScript React,

яка підтримується Facebook, для створення користувацьких інтерфейсів,

але замість націлювання на веб-переглядач спрямована на мобільні

платформи. Оскільки більшість коду, який ви пишете, можна

використовувати спільно між платформами, React Native спрощує

одночасну розробку як для Android, так і для iOS.

Подібно до React для Web, програми React Native написані з

використанням суміші JavaScript і XML розмітки, відомої як JSX. Потім, під

капотом, React Native викликає рідні API для рендеринга в Objective-C (для

iOS) або Java (для Android). Таким чином, програма відображатиметься за

допомогою реальних компонентів мобільного інтерфейсу, а не веб-

сторінок, а також виглядатиме та відчувати себе як будь-яке інше мобільне

додаток. React Native також надає інтерфейси JavaScript для API платформи,

тому програми React Native можуть отримувати доступ до функцій

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

Page 19: ДИПЛОМНА РОБОТА - ela.kpi.ua

19

У React Native в даний час підтримуються як iOS, так і Android, а

також потенціал для розширення на майбутні платформи. Facebook, Palantir

і TaskRabbit вже використовують його у виробництві для користувацьких

додатків.

Найбільший ризик - це, напевно, певна незрілість React Native,

оскільки проект все ще є відносно молодим [7]. Підтримка iOS була

випущена в березні 2015 року, а підтримка Android була випущена у вересні

2015 року. Деякі функції на iOS і Android все ще не підтримуються, і

спільнота все ще відкриває найкращі практики для використання цієї

технології.

Головним для успішності кожного програмного продукту є його

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

продукт. З часу представлення та виходу на ринок до створення стабільної

версії, що може задовільнити користувачів та завоювати долю ринку,

проходить довгий процес виправлення недоліків, вдосконалення системи,

враховуючи відгуки перших користувачів, впровадження нового

функціоналу.

Основна проблема цих двох технологій – бідна підтримка зі сторони

авторів цих інструментів. Також за рахунок додаткового шару виконання з

JS та C# швидкодія та ефективність системи суттєво падає.

2.2 Огляд архітектури мобільного застосунку

Архітектура надзвичайно важливий аспект в створенні програмного

забезпечення. Вона впливає на швидкість розробки, можливість підтримки,

тестування, гнучкість та стабільність програмного продукту.

На сьогодні в мобільній розробці існує парадигма «Чистої

архітектури» - набір рекомендацій для написання програми, що увібрав у

себе всі відомі рекомендації, такі як шаблони проектування та SOLID

Page 20: ДИПЛОМНА РОБОТА - ela.kpi.ua

20

принцип. Ця парадигма забезпечує написання чистого та стабільного

програмного коду, який легко тестувати, розширювати та підтримувати [8].

Чиста архітектура - це новий стиль архітектури, розроблений

Робертом Мартіном, більш відомим як «Дядько Боб». Ім'я дядька Бобу,

мабуть, знайоме всім, хто робив будь-яку розробку програмного

забезпечення за останні десятиліття, від його книг, таких як «Чистий код»,

до принципів SOLID, які використовуються і згадуються розробниками в

усьому світі, він добре відомий своїми лекціями та книгами з об'єктної

орієнтації.

На рисунку 2.1 зображено розподіл шарів системи, представлений

Робертом Мартіним.

Рисунок 2.1 – чиста архітектура Мартіна

Важливо зазначити, що запропонована ним структура архітектури не

орієнтована на об'єктно-орієнтовану парадигму, хоча може бути

реалізована за допомогою об'єктно-орієнтованої мови програмування,

Page 21: ДИПЛОМНА РОБОТА - ela.kpi.ua

21

використовуючи об'єктно-подібні конструкції і синтаксис, основна частина

пропозиції базується на процедурному мисленні.

Розпочнемо з переліку декількох пов'язаних архітектурних шаблонів,

з яких натхненний Мартін і створив ідею чистиї архітектури, а саме:

1. «Гексагональна архітектура» Алістера Кокберна

2. «Архітектура цибулі» Джеффрі Палермо

3. «Дані, комунікація та взаємодія» Тригве Реенскауга та Джеймса

О. Коплієна

Хоча ці архітектури дещо відрізняються в деталях, вони дуже схожі.

У всіх перелічених стилях існує декілька концепцій, які здаються дуже

подібними, і, дійсно, з точки зору програміста змішаної парадигми вони

можуть просто відрізнятися в деталях, але існують значні відмінності від

об'єктно-орієнтованої точки зору [8].

Наприклад «Дані, комунікація та взаємодія», хоча його назва

передбачає об'єктно-орієнтований підхід, на практиці це явно не так.

Викладені цілі цих авторів полягають у створенні змішаного

парадигмального підходу, який свідомо має процесуальні елементи для

протидії сприйнятим недолікам суто об'єктно-орієнтованого проектування.

Незалежно від того, чи є ці недоліки реальними чи ні, автори вирішили

відхилитися від об'єктної орієнтації в основі своєї пропозиції.

Те ж саме не можна сказати і про інші архітектурні стилі [8]. Хоча

можуть існувати тлумачення тих стилів, які призводять до суперечності

об'єктно-орієнтованих принципів, вони не роблять цього за допомогою

дизайну. Однак, всі вони мають одну і ту ж мету, тобто поділ проблем.

Розділення проблем є дуже важливим поняттям, але воно має дуже

різні значення в різних контекстах. У контексті чистої архітектури,

здається, мається на увазі повне відокремлення різних аспектів логіки,

наприклад відокремлення презентації, стійкості і можливо інших аспектів

від об'єктів, які фактично містять дані і контекст для всіх цих операцій.

Page 22: ДИПЛОМНА РОБОТА - ela.kpi.ua

22

Це дуже поширена інтерпретація для багаторівневих конструкцій,

також часто зустрічається в програмному забезпеченні Java Enterprise. Це

фактично є частиною найкращих практик для проектів підприємств, і йде

рука об руку з багаторівневими конструкціями.

Це, однак, небезпечна територія для об'єктно-орієнтованого

розробника. У об'єктно-орієнтаційному поділі занепокоєння маються на

увазі дві основні атрибути об'єктів, їх внутрішню монолітність і зв'язок з

іншими об'єктами. Простіше, але, мабуть, менш точно зазначено, це

означає, що об'єкти повинні містити кожну бізнес-функцію, яка високо

пов'язана з іншими функціями і даними в об'єкті.

Об'єкт-орієнтація не розрізняє функції за призначенням. Функція для

представлення деякого об'єкта на екрані або представлення об'єкта як XML

кожен біт так само діє, як і інші функції, які "тільки" змінюють стан об'єкта.

Тому всі вимоги, незалежно від технічних особливостей, впливають на

дизайн об'єкта, а «Презентація» є частиною бізнес-інтерфейсу об'єкта, якщо

це вимагається специфікацією.

Це, звичайно, не означає, що деталі Презентації повинні бути в бізнес-

об'єктах, але це означає, що принаймні деякі їхні абстрактні поняття

повинні знаходитись в об'єкті, і не повинно бути нічого поза об'єктом.

Ніщо фактично не вимагає поділу елементів програми, окрім

принципів згуртованості або зчепленням об’єктів, що продиктовані

зовнішніми архітектурними обмеженнями, такими як розподіл або інші

рамки архітектури. Тому мета розділення окремих аспектів поза об'єктом є

дуже небезпечною і, можливо, несумісною з об'єктно-орієнтованим

проектуванням.

Всі вони досягають цього поділу, розділяючи програмне

забезпечення на шари.

Шари - це хороший спосіб розділити об'єкти, які природно

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

Page 23: ДИПЛОМНА РОБОТА - ela.kpi.ua

23

мережевий стек, який буде складатися з різних груп об'єктів, що

відображають структуру шарів ISO / OSI. Можливо, існуватимуть об'єкти

для мережевого рівня, які пропонують можливості маршрутизації, і,

ймовірно, існуватимуть об'єкти, відповідальні за транспортний шар, що

реалізує протоколи TCP і UDP. Об'єкти транспортного шару мали б доступ

до об'єктів мережевого шару, але не навпаки, отже, вони б сформували

групу шарів структури [10].

На рисунку 2.2 зображено основні шари системи, що містять логіку

застосунку.

Рисунок 2.2 – основні шари системи

Така інтерпретація шарів була б дуже ефективним способом

розкласти проблему реалізації мережного стека. Однак, це не те, що

пропонується вище. Чиста архітектура пропонує розділити різні аспекти

одного об'єкта на декілька різних частин, що, здається, не сумісні з

основними принципами об'єктно-орієнтованого проектування.

Page 24: ДИПЛОМНА РОБОТА - ela.kpi.ua

24

Кожний з цих архітектурних парадигм надає системі цілий ряд

переваг. Розглянемо більш детальну кожну з них.

По-перше, система набуває незалежності від сторонніх факторів.

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

забезпечення, що навантажується ознаками.

Якщо розглядати контекст, у якому робиться це твердження, він,

здається, припускає, що “бізнес-об'єкти” повинні бути повністю

незалежними від структур та зовнішніх бібліотек. Немає математичної

бібліотеки, бібліотеки "загального користування", бібліотеки повідомлень,

без CDI, без EJB, і, звичайно, немає бібліотеки презентацій або баз даних.

Можливо, всі ці рішення повинні прийматися з урахуванням

функціональних і нефункціональних вимог, а не категорично забороняти

всім без будь-яких чітких і поточних переваг.Проте є хороша думка, що

сама архітектура не повинна залежати від бібліотеки (або фреймворку). Це

може бути корисним, щоб трохи відділяти бібліотеку за рамки основного

проекту.

Бібліотека - це просто набір об'єктів (класів), які мають певну

функціональність. Ми залежать від бібліотек, тому що ми не хочемо

повторно використовувати деякі функціональні можливості, такі як

введення-виведення, мережевий зв'язок, моніторинг бази даних і тому

подібне [11]. Бібліотека також пропонує функціональність, але в той же час

накладає певну форму управління дизайном. Він пропонує свою

функціональність, лише якщо деякі або всі частини коду, які

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

реалізовані в заданій парадигмі або шаблоні.

Наявність залежності від деяких фреймворків в основі програми

зазвичай має багато недоліків, і вищезгадана думка може правильно

трактуватись, що сама «архітектура» часто стає залежною від бібліотеки.

Це може мати катастрофічний вплив на ремонтопридатність пізніше в житті

Page 25: ДИПЛОМНА РОБОТА - ela.kpi.ua

25

програмного забезпечення, тому фреймворків слід уникати, якщо це взагалі

можливо. Однак, повна незалежність від усіх залежностей, як це

передбачено вище, не може бути ні досяжною, ні бажаною.

По-друге, система стає пригідною до тестування. Бізнес-правила

можуть бути перевірені без інтерфейсу користувача, бази даних, веб-

сервера або будь-якого іншого зовнішнього елемента.

Тестування є важливим і бажаним аспектом, і вона повинна бути

можливою без додаткових об'єктів або зовнішніх систем. Можливість

писати одиничні тести для класу насправді є хорошим показником для

гарного дизайну. Однак, це правило має включати не тільки «бізнес-

правила». Блокові тести також повинні охоплювати інтерфейс користувача

і стійкість, точно так само, без зовнішніх елементів. Поняття тестування не

повинно використовуватися для того, щоб припустити, що користувацький

інтерфейс або шар представлення за своєю суттю менш важливі, або

перешкоджають тестуванню інших аспектів об'єкта.

Наступна перевага – незалежність від інтерфейсу. Інтерфейс

користувача може легко змінюватися, не змінюючи решту системи. Веб-

інтерфейс користувача може бути замінений інтерфейсом консолі,

наприклад, без зміни бізнес-правил.

Не менш важливою є незалежність від баз даних. Ви можете поміняти

Oracle або SQL Server, для Mongo, BigTable, CouchDB або щось інше. Ваші

бізнес-правила не пов'язані з базою даних.

Це дуже спірне, чи перемикання веб-додатків на консольне додаток,

або перемикання реляційної бази даних програми на NoSQL - це звичайні

випадки використання в розробці програмного забезпечення. Це, звичайно,

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

програмного забезпечення присвячено цим завданням. Ймовірно, набагато

більше роботи виконується для виправлення помилок і впровадження нових

функцій, які не вимагають повного перемикання технологій.

Page 26: ДИПЛОМНА РОБОТА - ela.kpi.ua

26

Таким чином, ця повна незалежність інтерфейсу користувача, бази

даних і взагалі всього зовнішнього світу буде бажаною лише в тому

випадку, якщо ця незалежність буде незначною або дуже низькою. Проте

це не так, оскільки вводяться додаткові «шари», з додатковими межами, які

вводять у додаток багато зайвої складності. Принцип «Keep It Simple»

повинен застосовуватись, і це рішення не слід приймати лише для того, щоб

потенціал був трохи більш гнучким для теоретичного використання.

На рисунку 2.3 зображено архітектуру системи, що слідує принципам

чистої архітектури.

Рисунок 2.3 – чиста архітектура системи

За винятком перерахованих вище рідкісних випадків використання,

об'єкти повинні добре усвідомлювати весь спектр бізнес-функцій, які інші

об'єкти можуть попросити їх виконати. Цей діапазон бізнес-функцій

повинен включати принаймні деякі абстракції представлення, якщо система

повинна відповідати об'єктно-орієнтованим принципам.

Інкапсуляційність функцій користувальницького інтерфейсу та

представлення повністю означають, що будь-які зміни в "бізнес-об'єктах"

Page 27: ДИПЛОМНА РОБОТА - ela.kpi.ua

27

або "ділових правилах" не будуть впливати на решту системи, що їх

використовує. Згідно з об'єктною орієнтацією, зміни до деталей, як

додавання або видалення приватних полів в об'єкті, не повинні викликати

зовнішніх змін. Це дуже важлива властивість, яка сильно сприяє

ремонтопридатності коду і, можливо, неможливо досягти, якщо частини

функціональності об'єкта є зовнішніми для самого об'єкта.

Абстрактний шар Use case зберігає і реалізує у собі всі випадки

використання системи.

Одним з ключових інструментів розробників для вирішення великих

проблем в інформатиці називається декомпозиція. Це просто означає, що

ми, люди, занадто обмежені для роботи з великими моделями і складними

алгоритмами, тому ми повинні розділити проблеми на менші частини. Це

можна зробити кількома способами.

Найпростіший спосіб розбити проблему - це спробувати перелічити

кроки, необхідні для виконання завдання. Візьмемо, наприклад, кроки для

здійснення переказу коштів з облікового запису:

1. Перевірте наявність номера облікового запису

2. Отримати тип облікового запису

3. Визначити ліміт передачі для даного типу облікового запису

4. Продовжити лише тоді, коли вказана сума не перевищує ліміту

5. Переконайтеся, що на рахунку достатньо грошей

6. Відняти значення з рахунку

7. Створіть переказ на суму

Це, звичайно, дуже спрощено, але демонструє, як більша проблема

перенесення тепер розділена на 7 менших, простіших кроків, які потім

можуть бути розділені в міру необхідності, поки не стануть досить легким

для безпосереднього кодування. Це те, що широко відоме як процедурна

конструкція або процедурна декомпозиція. Це процедурний процес, тому

Page 28: ДИПЛОМНА РОБОТА - ela.kpi.ua

28

що ми стурбовані тим, які кроки повинні відбутися, під час яких ми

отримуємо та змінюємо дані (в іншому місці) за необхідності.

Опис цього грошового переказу називається “Випадок використання”

або Use case. Оскільки частина “даних” знаходиться в шарі нижче (“Data”),

запропонований шар Use case, ймовірно, міститиме кроки, необхідні для

його виконання, подібно до вищезазначеного.

Окремі кроки, перераховані послідовно, звучать інтуїтивно. Дійсно,

це саме те, що шаблон «Дані, комунікація та взаємодія» також пропонує, і

критикує об'єктну орієнтацію для того, щоб не робити.

Проблема з цим підходом полягає в тому, що вона, здається, не

масштабується. Поки він містить обмежений набір різних випадків

використання, підхід працює, але як тільки вводяться перекриваються

функції, він починає руйнуватися.

Наприклад, введемо внутрішній випадок використання грошових

переказів, де кроки майже однакові, але передача не переходить на кліринг,

замість цього вона переходить безпосередньо на інший обліковий запис.

Тепер проблема полягає в тому, що ці два кроки діляться. Обидва повинні

перевірити, чи є гроші, і повинні перевірити межі, і т.д.

Це робить помилку всієї справи невиправдано складною. Ми вже

вирішили перевірки, але ми повинні знову подумати про них для цього

нового випадку. Якщо ми забудемо про це, у нас є проблема, і якщо ні, то

ми збільшили наше пізнавальне навантаження, навіть якщо нам просто

потрібно скопіювати або повторно використати його. Хіба не було б

приємно, якби ми могли просто забути про неї, як тільки ми її вирішимо, і

це буде автоматично застосовано, коли вирахувати гроші з рахунку?

Це саме те, що робить об'єктна орієнтація. Об'єкт-орієнтація пропонує

інший вид декомпозиції, де ми насправді не думаємо про «кроки», які

необхідно вжити, але про «речі», які необхідно залучити. У цьому випадку

«Рахунок», «Переказ», «Гроші» і т.д. Всі ці речі можуть мати свої власні

Page 29: ДИПЛОМНА РОБОТА - ela.kpi.ua

29

правила і поведінку, тому немає необхідності думати про те, чи може

«крок» зіпсувати обліковий запис, або передати більше грошей, ніж на

рахунку, оскільки об'єкт Рахунок не дозволив би цього. По суті, ми не

можемо вирахувати гроші з рахунку безпосередньо, ми повинні попросити

Рахунок відняти його для нас, тим самим автоматично зробивши всі

необхідні перевірки. Цей підхід, однак, спирається на той факт, що «дані»

приховані за операціями, які вже мають частини Use case логіки. Дійсно,

якщо всі об'єкти розроблені правильно, фактично не повинно бути нічого,

що залишилося б від випадку використання, яке було б реалізовано окремо.

Враховуючи відмінності між цими двома підходами, здається, що

запропонований шар використання може краще підходити для

процедурного підходу і може бути повністю несумісний з об'єктно-

орієнтованим.

Висновки до розділу 2

У даному розділі було описано існуючі технології, що

використовуються для написання крос-платформних мобільних застосунків

та їх основні проблеми. Також, було описано найбільш вдалу архітектуру

додатку, що вирішує більшість проблем, які виникають при розробці ПЗ.

Page 30: ДИПЛОМНА РОБОТА - ela.kpi.ua

30

3 Аналіз технології Kotlin Native та її ефективність в

розробці мобільних застосунків

Kotlin Native - це технологія для компіляції програмного коду,

написаного на Kotlin до бінарних файлів, які можуть працювати без

віртуальної машини. Такий підхід стає можливим за допомогою LLVM

компілятора, що базується на компіляторі Kotlin і реалізації стандартної

бібліотеки Kotlin.

Kotlin Native призначений насамперед для компіляції для платформ,

де віртуальні машини не бажані або неможливі, наприклад, вбудовані

пристрої або iOS. Він вирішує ситуації, коли розробник повинен створити

автономну програму, яка не вимагає додаткової роботи або віртуальної

машини. Kotlin Native підтримує двосторонню взаємодію з платформоюза

допомогою механізму expect/actual. З одного боку, компілятор створює:

• виконуваний файл для багатьох платформ;

• статичну бібліотеку або динамічну бібліотека з файлами C для

проектів C / C ++;

• бібліотеку Apple для проектів Swift та Objective-C.

З іншого боку, Kotlin Native підтримує можливість взаємодії з

існуючими бібліотеками безпосередньо написаними на Kotlin Native, а

саме:

• статичні або динамічні бібліотеки;

• C, Swift та Objective-C бібліотеки.

Складений Kotlin код можна легко включити до існуючих проектів,

написаних на мовах C, C ++, Swift, Objective-C та інших мовах. Також легко

використовувати існуючий рідний код, статичні або динамічні бібліотеки

C, фреймворки Swift / Objective-C, графічні двигуни і все інше

безпосередньо з Kotlin Native.

Page 31: ДИПЛОМНА РОБОТА - ela.kpi.ua

31

Бібліотеки Kotlin Native допомагають розділити Kotlin код між

проектами. POSIX, gzip, OpenGL, Metal, Foundation і багато інших

популярних бібліотек і фреймворків Apple попередньо імпортуються і

включаються до бібліотеки Kotlin Native у пакет компіляторів [12].

Технологія Kotlin Native має високий потенціал для розробки крос-

платформних мобільних додатків.

На рисунку 3.1 зображено механізм компіляції коду для двох

платформ, використовуючи компілятор специфічний LLVM компілятор,

який реалізує технологія Kotlin Native.

Рисунок 3.1 – приклад компіляції для iOS та Android

3.1 LLVM компілятор

Проект інфраструктури компілятора LLVM – це колекція модульних

і багаторазових технологій компілятора і інструментів, які

використовуються для розробки компіляторів високого та низького рівня.

Page 32: ДИПЛОМНА РОБОТА - ela.kpi.ua

32

LLVM написаний на C ++ і призначений для роботи під час

компіляції, часу зв'язку, часу виконання та оптимізації програм, написаних

на довільних мовах програмування [13]. Спочатку реалізований для C і C

++, лексичний агностичний дизайн LLVM з тих пір породив широкий

спектр високорівневих компіляторів: мови з компіляторами, які

використовують LLVM включають ActionScript, Ada, C #, Common Lisp,

Crystal , CUDA, D, Delphi, Dylan, Fortran, Графічна мова програмування G,

Halide, Haskell, Java байт-код, Julia, Kotlin, Lua, Objective-C, OpenWeb

Shading, Python, Ruby, Rust, Skala, Swift.

LLVM може забезпечити середні шари повної системи компіляторів,

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

оптимізований код, який може бути перетворений і пов'язаний з машинно-

залежним кодом мови асемблера для цільової платформи. LLVM може

приймати інфраструктуру з інструментальної колекції компіляторів GNU

(GCC), що дозволяє використовувати її з широким колом існуючих

компіляторів, написаних для цього проекту.

LLVM може також генерувати переміщуваний машинний код під час

компіляції або часу з'єднання або навіть двійкового машинного коду під час

виконання.

LLVM підтримує незалежний від мови набір команд і систему типів.

Кожна команда знаходиться у формі статичного одиночного призначення,

тобто кожна змінна (називається типізований регістр) призначається один

раз, а потім заморожується. Це допомагає спростити аналіз залежностей

між змінними. LLVM дозволяє компілювати код статично, як це робиться в

традиційній системі GCC, або залишити для пізньої компіляції до

машинного коду через компіляцію (JIT), подібну до Java. Система типів

складається з основних типів, таких як цілі числа або числа з плаваючою

точкою і п'ять похідних типів: вказівники, масиви, вектори, структури і

функції. Конструкт типу в конкретній мові може бути представлений

Page 33: ДИПЛОМНА РОБОТА - ela.kpi.ua

33

шляхом об'єднання цих основних типів в LLVM. Наприклад, клас у C ++

може бути представлений сумішшю структур, функцій і масивів вказівників

функцій.

Компілятор JLVM JIT може оптимізувати непотрібні статичні гілки з

програми під час виконання і, таким чином, є корисним для часткової

оцінки в тих випадках, коли програма має багато варіантів, більшість з яких

можна легко визначити непотрібними в конкретному середовищі [14]. Ця

функція використовується в конвеєрі OpenGL Mac OS X Leopard (v10.5) для

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

Графічний код у стеку OpenGL можна залишити в проміжному

поданні, а потім скомпілювати при запуску на цільовій машині. На системах

з високоякісними графічними пристроями (GPU), отриманий код

залишається досить тонким, передаючи інструкції GPU з мінімальними

змінами. У системах з низьким кінцем GPU LLVM буде компілювати в

необов'язкові процедури, які виконуються на локальному центральному

процесорі (CPU), що імітує інструкції, які GPU не може виконувати

внутрішньо.

Для задачі виконання скомпільованих програм, GCC раніше

перевищував швидкість LLVM на 10% в середньому в 2011 році. Нові

результати у 2013 році вказують, що LLVM тепер наздогнав GCC в цій

області, і тепер компілює бінарні файли приблизно однакової

продуктивності.

3.2 Розробка специфічних для платформи модулів

Робота на всіх платформах - це явна мета Kotlin. Спільне

використання коду між платформами – передумова до цієї мети. Завдяки

підтримці JVM, Android, JavaScript, iOS, Linux, Windows, Mac і навіть

вбудованих систем, таких як STM32, Kotlin може обробляти будь-які

Page 34: ДИПЛОМНА РОБОТА - ela.kpi.ua

34

компоненти сучасної взаємодії з додатком. І це приносить неоціненну

користь від повторного використання коду та досвіду, заощаджуючи

зусилля для виконання складніших завдань, ніж реалізувати все двічі або

кілька разів.

Загалом, мультиплатформність не полягає у компіляції всього коду

для всіх платформ. Ця модель має свої очевидні обмеження, а саме, що

сучасним додаткам необхідний доступ до унікальних особливостей

платформ, на яких вони працюють. Kotlin не обмежує вас загальнию

підмножиною всіх API у світі [15]. Кожен компонент може спільно

використовувати інші коди, але може отримати доступ до API платформи в

будь-який час за допомогою механізму expect/actual, передбаченого мовою.

На рисунку 3.2 зображено приклад спільного використання коду та

взаємодії між загальною і платформною логікою отримання поточного часу

системи.

Рисунок 3.2 – приклад роботи механізму expect/actual

Для сучасної розробки мобільних застосунків необхідна велика

кількість сторонніх бібліотек. Незалежна логіка, що може

використовуватись багаторазово виноситься в окремі модулі, для

використання в інших проектах. Такий підхід економить багато часу на

написання коду та його тестування. Це можуть бути специфічні бібліотеки

для з певним модулем (камера, навігація), або бібліотеки сторонніх сервісів,

Page 35: ДИПЛОМНА РОБОТА - ela.kpi.ua

35

таки як Google Maps або Firebase. Також сторонні бібліотеки можуть

вирішувати типові проблеми програмування або реалізувати кардинально

інші підходи для проектування програмного продукту, такі як RxJava

(реалізація реактивних потоків) або Arrow(реалізація функціонально

підходу програмування).

На жаль, більшість бібліотек, що використовуються в мобільній

розробці під Android або iOS, не підтримують взаємодію з Kotlin Native.

Оскільки кожна з них в своїй реалізації має специфічні елементи. Однак

ситуація стрімко покращується, та розробники бібліотек додають

підтримку Kotlin Native з окремими модулями-реалізаціями для кожної з

платформ.

Рисунок 3.3 описує приклад використання бібліотеки SqlDelight, що

використовується для зручної роботи з базою даних SQLite.

Рисунок 3.2 – приклад роботи механізму expect/actual

використовуючи сторонню бібліотеку

Такий підхід використовує абстрактний контракт для використання

певної сутності, реалізація якої залежить від певних платформних засобів.

Основою такої ідеї став принцип підстановки Лісков, однак замість

Page 36: ДИПЛОМНА РОБОТА - ela.kpi.ua

36

використання інтерфейсу в якості оголошення контракту, був використавий

особливий синтаксис мови програмування.

3.3 Дослідження ефективності розробки

Kotlin native має кардинально інший підхід до створення та

впровадження крос-платформного системи. На відміну від Xamarin та React

native, ця технологія не має можливостей до написання спільного

користувацького інтерфейсу, що, в свою чергу, позбавляє від більшості

системних залежностей, які вимагають специфічні платформні драйвери

або створення додаткового шару виконання.

Основна ідея – створення спільної логіки, яка мати велику швидкодію

за рахунок компіляції в бінарний код. Отже, розробники створюють лише

спільну логіку, яка буде використовуватись інтерфейсом, написаним на

офіційних технологіях, таких як Java або Kotlin для Android та Objective-C

або Swift для iOS [17].

Бізнес-логіка – найважливіший та найскладніший шар в будь-якому

мобільному додатку, який вимагає повне покриття тестами для ефективної

підтримки та можливості розширення без зменшення стабільності

продукту. Kotlin Native дозволяє поширювати цю логіку між платформами.

Окрім бізнес-логіки поширюються і усі тести, якими була покрита ця

логіка.

На прикладі розробленого додатку (Розклад занять для студентів та

викладачів) вдалось обрахувати кількість спільного коду, кількість коду, що

вимагає специфіку платформи та кількість тестів, що вдалось поширити, а

саме:

1. шар бази даних (Database layer), що представлений DAO

класами, моделями даних, механізмом міграції та SQL-драйвером;

Page 37: ДИПЛОМНА РОБОТА - ela.kpi.ua

37

2. шар інтернет мережі(API layer), який містить у собі доступ до

API та парсинг JSON об’єктів, отриманих з мережі інтернет;

3. шар даних(Data layer), який містить реалізації репозиторіїв, які

зберігають логіку обробки даних в середині додатку, та їх обмін між базою

даних та мережею інтернет;

4. шар бізнес-логіки(Domain layer), що містить Use cases, основні

елементи логіки, що використовують репозиторії для маніпуляції даними

та основні моделі.

На жаль, окрім основних елементів було необхідно створювати

платформні реалізації для отримання реалізації SQL-драйвера та механізм

обчислення поточного часу та механізм логування системи, які також

мають залежність від системи.

Також потрібно було повністю створювати користувацький

інтерфейс, що займає значну частину мобільного додатку, проте вимагає

менше інженерної праці за рахунок своєї легкості та не потребує написання

тестів.

Отже, незважаючи на специфічні елементи та повної реалізації

інтерфейсу для кожної з платформ, ефективність розробки залишається на

високому рівні, а саме – вдалося поширити між системами:

1. 80 відсотків усієї логіки застосунку. Лише 20 відсотків

написаного коду займають платформні специфікації. Однак, це число буде

змінюватись у користь Kotlin native при маштабуванні проекту, оскільки

більшість специфічного коду може використовуватись повторно;

2. 90 відсотків усіх тестів. Деякі платформні специфікації також

вимагають покриття тестів.

3.4 Недоліки технології Kotlin native

Page 38: ДИПЛОМНА РОБОТА - ela.kpi.ua

38

Після детального аналізу проблем, що виникали під час розробки

програмного продукту варто виділити дві основні проблеми, а саме –

обмежена кількість сторонніх бібліотек, що мають підтримку цієї

технології та нестабільність інструменту побудови проекту.

Обмежена кількість сторонніх бібліотек – надзвичайно вагома

проблема, яка сильно впливає на швидкість розробки. Проте технологія

дуже молода і ситуація стрімкими темпами покращується. А через

популярність Kotlin та підтримку зі сторони Google та JetBrains можна з

упевненістю сказати, що ця проблема буде вирішена.

Наступним недоліком стала нестабільність системи побудови

проекту, а саме Gradle плагіна, що надає підтримку Kotlin native. Ситуація

також покращується. За час роботи над проектом було представлено дві

нові версії плагіна, що вирішили багато проблем та помилок, що виникали

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

Висновки до розділу 3

У даному розділі було досліджено ефективність процесу розробки

крос-платформних мобільних додатків використовуючи технологію Kotlin

native. Також було розглянуто технічні аспекти роботи технології,

визначено її переваги та недоліки.

Page 39: ДИПЛОМНА РОБОТА - ela.kpi.ua

39

4 ОГЛЯД ПРОГРАМНОЇ РЕАЛІЗАЦІЇ

ДОДАТКУ «РОЗКЛАД»

Програмний продукт складається з трьох частин, а саме: спільний

модуль написаний на Kotlin native, який містить в собі більшість логіки

мобільного застосунку, реалізацію для Android написаний на Kotlin та

реалізацію для iOS, що використовує мову програмування Swift. Два

останні зберігають у собі реалізації користувацьких інтерфейсів, що

використовують спільну бізнес-логіку з першого модуля.

Рисунок 4.1 – структура програмної реалізації

4.1 Створення Use case об’єкта

Розглянемо приклад реалізації Use case об’єкта. Об’єкт

«SchedulerUseCase», що розташований у модулі Domain, містить у собі

об’єкти репозиторіїв «LessonRepository» та «SettingRepository», які надають

Page 40: ДИПЛОМНА РОБОТА - ela.kpi.ua

40

доступ до даних застосунків. Use case містить у собі метод

«loadCurrentGroupScheduler», який відповідає за завантаження розкладу

користувача.

На рисунку 4.2 зображена структура Use case.

Рисунок 4.2 – структура SchedulerUseCase

Об’єкти цих репозиторіїв не створюються вручну. Ц програмі

використовується шаблон Dependencies injection, який займається

моніторингом створення об’єктів.

4.2 Приклад реалізації репозиторія

Репозиторій – це шаблон проектування, що використовується для

інкапсуляції логіки обробки даних. Він представляє з себе «чорний ящик»,

який надає інтерфейс для зовнішнього користування незважаючи на

Page 41: ДИПЛОМНА РОБОТА - ela.kpi.ua

41

внутрішню реалізацію. Розглянемо «LessonRepository». Цей об’єкт містить

у собі логіку обробки уроків, що представленні моделлю «Lesson», а саме

зчитування з мережі та кешування у локальній базі даних.

На рисунку 4.3 зображено зовнішній інтерфейс репозиторія.

Рисунок 4.3 – структура LessonRepository

Як джерела даних використовується сутність «LessonDataStore», що

має реалізації у модулях «API» «DB».

4.3 Реалізації LessonDataStore

Для розподілу логіки кешування в локальній базі даних та зчитування

даних з мережі інтернет використовується інтерфейс LessonDataStore, який

має два відповідних підінтерфейса, а саме: Cache та Remote реалізація яких

лежить в інших незалежних модулях. Це робить модулі, що відповідають за

зв’язок з мережею та базою даних повністю незалежними від інших

Page 42: ДИПЛОМНА РОБОТА - ela.kpi.ua

42

модулів. Це дозволяє легко тестувати кожний з них. Потрібно лише

підставити тестову реалізацію зовнішніх залежностей.

На рисунку 4.4 та 4.5 зображено реалізації Cache та Remote, для

роботи з об’єктом «Lesson».

Рисунок 4.4 – реалізація LessonDataStore.Remote

Рисунок 4.4 – реалізація LessonDataStore.Cache

Page 43: ДИПЛОМНА РОБОТА - ela.kpi.ua

43

5 ВИКОРИСТАННЯ РОЗРОБЛЕНОГО

ПРОГРАМНОГО ПРОДУКТУ

При вході в додаток, в першу чергу, з’являється екран авторизації, де

користувач повинен ввести свою групу.

Рисунок 5.1 – вікно входу в додаток

Після цього відкривається головний екран, який містить розклад для

вибраної групи по днях тижня, дату, час та аудиторію.

Рисунок 5.2 – головний екран додатку

Page 44: ДИПЛОМНА РОБОТА - ela.kpi.ua

44

При натисканні на потрібний предмет з’являється вікно з детальною

інформацією: тип заняття, викладач, аудиторія та розташування на карті. В

цьому вікні також є можливість внесення нотаток з фотографіями.

Рисунок 5.3 - вікно з детальною інформацією про предмет

У вікні «Викладачі» при натисканні на певного викладача, з’являється

його розклад, що по структурі аналогічний до студентського розкладу.

Рисунок 5.4 - вікно «Викладачі»

Page 45: ДИПЛОМНА РОБОТА - ela.kpi.ua

45

6 ЗАСОБИ РЕАЛІЗАЦІЇ

6.1 Android studio

Android Studio - це інтегроване середовище розробки (IDE) для

роботи з платформою Android. Android Studio створена на програмному

забезпеченні IntelliJ IDEA від компанії JetBrains і є офіційним засобом

розробки Android додатків. Дане середовище розробки доступне для

Windows, OS X і Linux.

Особливості середовища розробки:

1. Розширений редактор макетів: WYSIWYG, здатність

працювати з UI компонентами за допомогою Drag-and-Drop, функція

попереднього перегляду макета на декількох конфігураціях екрану.

2. Збірка додатків, заснованих на Gradle.

3. Різні види збірок і генерація декількох apk файлів.

4. Рефакторинг коду.

5. Статичний аналізатор коду (Lint), що дозволяє знаходити

проблеми продуктивності, несумісності версій і т.д.

6. Вбудований ProGuard і утиліта для підпису додатків.

7. Шаблони основних макетів і компонентів Android.

Android - операційна система для смартфонів, інтернет-планшетів,

електронних книг, цифрових програвачів, наручних годинників, ігрових

приставок, нетбуків, смартбуків, окулярів Google, телевізорів і інших

пристроїв. В майбутньому планується підтримка автомобілів, побутових

роботів. Дане середовище засноване на ядрі Linux і власній реалізації

віртуальної машини Java від Google і дозволяє створювати Java-додатки, що

керують пристроєм через розроблені Google бібліотеки. Android Native

Development Kit дозволяє переносити бібліотеки і компоненти додатків,

написані на Сі та інших мовах. Близько 86% смартфонів на даний момент

Page 46: ДИПЛОМНА РОБОТА - ela.kpi.ua

46

використовують операційну систему Android. При цьому за весь 2018 рік

було продано більше 1 мільярда Android устройств.

6.2 Kotlin

Kotlin — статично типізована мова програмування, що працює поверх

JVM і розробляється компанією JetBrains. Також компілюється в JavaScript.

Мову названо на честь острова Котлін у Фінській затоці, на якому

розміщена частина Кронштадту. Автори ставили перед собою ціль створити

лаконічнішу та типо-безпечнішу мову, ніж Java, і простішу, ніж Scala.

Наслідками спрощення, порівняно з Scala стали також швидша компіляція

та краща підтримка IDE.

Мова розробляється з 2010 року, публічно представлена в липні 2011.

Сирцевий код було відкрито в лютому 2012. В лютому було випущено

milestone 1, який містив плагін для IDEA. У червні — milestone 2 з

підтримкою Android. У грудні 2012 року вийшов milestone 4 та забезпечив

підтримку Java 7. Станом на листопад 2015 року основні можливості мови

стабілізовані, готується реліз версії 1.0. В грудні 2015 року з'явився реліз-

кандидат версії 1.0, а 15 лютого 2016 року відбувся реліз версії 1.0. З 17

травня 2017 року входить в список офіційно підтримуваних мов для

розробки додатків для платформи Android. Позиціонується розробниками

як об'єктно-орієнтована мова промислового рівня, а також як мова, яка

зможе замінити Java. При цьому мова повністю сумісна з Java, що дозволяє

розробникам поступово перейти з Java на Kotlin. Зокрема, в Android мову

вбудовується за допомогою Gradle, що дозволяє для існуючого Android-

додатку впроваджувати нові функції на Kotlin без переписування самої

програми. Синтаксис мови схожий на Pascal, TypeScript, Haxe, PL / SQL, F#,

Go і Scala, C ++, Java, C # і D. При оголошенні змінних і параметрів типи

даних вказуються після назви (роздільник двокрапка). Крапка з комою, як

Page 47: ДИПЛОМНА РОБОТА - ela.kpi.ua

47

роздільник операторів, є необов'язковою, так само як в Scala і Groovy, в

більшості випадків перенесення рядка досить, щоб компілятор зрозумів, що

вираз закінчився. Крім об'єктно-орієнтованого підходу, Kotlin також

підтримує процедурний стиль з використанням функцій. Як і в мовах

C/C++/D, точкою входу в програмі є функція "main", яка приймає масив

параметрів командного рядка. Програми на Kotlin також підтримують Perl

і Unix / Linux shell стиль інтерполяції рядків. Kotlin також підтримує

виведення типів [18].

Розробники Android пишуть, що вони спостерігали «сходження»

Kotlin всі останні роки. Kotlin описують як вражаючу і лаконічну мову, яка

відкриває більше можливостей і з якою приємно працювати. Вона має

підвищену продуктивність: програмний код на ньому виходить в

середньому на 40% коротше, ніж на інших мовах, а також Kotlin дозволяє

не допускати деякі помилки в коді. Одним з визначальних чинників

популярності Kotlin стало те, що він сумісний з Java, яка вже

використовується при розробці додатків під Android. Тепер, коли

програмісти починають створювати новий додаток в офіційному

середовищі розробки Android Studio, вони відразу можуть включити плагін

«підтримка Kotlin». Також можна конвертувати вже створені рядки коду на

інших мовах в мову Kotlin, вставляти блоки на інших мовах в рядки коду на

Kotlin. У майбутньому для мови буде розроблятися більше бібліотек і

інструментів, більше навчальних матеріалів, простіше буде знайти рішення

для можливих проблем. Відсутність гарантій підтримки мови з боку Google

відлякувала багатьох розробників від переходу на Kotlin. Навіть якщо мова

дуже подобається, програміст завжди думає про ризик, що в якийсь момент

ця мова просто перестане працювати. Тепер є гарантія того, що працювати

Kotlin не перестане, і ми очікуємо, що кількість користувачів мови різко

зросте. Припускають, що багато компаній з часом перейдуть на Kotlin

повністю, хоча технічно їх до цього нічого не змушує, це просто питання

Page 48: ДИПЛОМНА РОБОТА - ela.kpi.ua

48

переваг. Він додав, що Kotlin дуже активно розвивається. Команда

розробників зараз працює над build-системою, швидкістю компіляції,

покращенням продуктивності IDE, додаванням в інструментарій нових

можливостей, в тому числі пов'язаних з інтеграцією в Android Studio. Також

йде робота над мультиплатформенними проектами (можливість

компілювати один і той же код під кілька платформ), цілий ряд мовних

поліпшень знаходиться в стадії дизайну. Варто зазначити концепція мови

Kotlin, за яким він завжди був і залишиться безкоштовним для розробників,

тобто open source project. Це означає, що мова не прив'язана до якої-небудь

окремої компанії, а вихідний код розповсюджується під вільною ліцензією.

Завантажити продукт можна. Щоб підтримувати розвиток Kotlin,

компаніями Google і JetBrains буде створено некомерційне партнерство.

Також в рамках «місії» Android дуже важливо, що автори Kotlin створюють

навколо свого продукту співтовариство людей, які професійно займаються

розробкою на цій мові і люблять ділитися досвідом. Наприклад,

проводяться конференції, де розробники можуть отримувати щоденні

новини та поради про програмний продукт, зустрічатися на місцевому рівні.

6.3 Gradle

Gradle - система автоматичного збирання, побудована на принципах

Apache Ant і Apache Maven [18]. В Eclipse використовувалася система Ant,

але більшість розробників навіть не помічало її роботи. В основному

можливості системи використовувалися в конторах для автоматизації

різних завдань. В Android Studio такий номер не пройде. Gradle

супроводжує розбробника постійно. Gradle не є винаходом для Android

Studio, система була розроблена раніше і використовувалася в додатках з

Java, Scala та з іншими мовами. Система збирання Gradle дуже потужна і

складна, щоб про неї розповісти в двох словах. Є цілі книги про неї. Самі

Page 49: ДИПЛОМНА РОБОТА - ela.kpi.ua

49

команди в Gradle представляють собою звичайний текст з використанням

синтаксису Groove для конфігурації. Альтернативою Gradle є система

автоматичного збірки Maven. Ці дві системи з одного боку різні, а з іншого

боку мають і ряд схожих властивостей. Gradle заснований на графі завдань

(task), які можуть залежати один від одного. Завдання виконують певну

роботу. Maven ж використовує модель певних фаз (phase), до яких

приєднуються певні "цілі" (goals). У цих goals і виконується якась робота.

Однак, при таких різних підходах в обидвох системах управління

залежностями відбувається схожим чином.

Page 50: ДИПЛОМНА РОБОТА - ela.kpi.ua

50

ВИСНОВКИ

Проаналізовано сферу розробки крос-платформних мобільних

застосунків. Розглянуто популярні технології та виявлено їх недоліки та

переваги. Виявлено проблеми, що зустрічаються під час розробки крос-

платформних застосунків. Описано технологію Kotlin native як

альтернативу існуючим на ринку технічним рішенням. Проведено аналіз

архітектури мобільного додатку.

Розроблено мобільний застосунок «Розклад занять для студентів та

викладачів» для платформ Android та iOS, що містить спільну логіку,

написану на Kotlin native.

Проведено аналіз ефективності розробки з використанням технології

Kotlin native. Наведено переваги технології, її технічні аспекти та недоліки.

Page 51: ДИПЛОМНА РОБОТА - ela.kpi.ua

51

СПИСОК ВИКОРИСТАНИХ ДЖЕРЕЛ

1. Гобрик, Д. А. Человеко-машинный интерфейс / Д. А. Гобрик; науч. рук.

И. И. Гутич // Материалы 70-й студенческой научно-технической

конференции : [тезисы докладов студентов БНТУ] / ред. колл.: Е. Е.

Трофименко [и др.]. — Минск: БНТУ, 2015. — С. 45-46.

2. Аболихина Е.С. Перспективы развития смарт-технологий для

городской транспортной инфраструктуры / Е.С. Аболихина, И.А.

Ромашкова, А.А. Попов // Постулат. — 2017. — №12. — С. 23-29.

3. Взаємодія програмних систем [Електронний ресурс]. — Режим

доступу до ресурсу: https://geektimes.com/post/282922/

4. Причины возникновения проблем совместимости программного

обеспечения [Електронний ресурс] – Режим доступу до ресурсу:

http://helpiks.org/7-46217.html

5. Шабан М.Р. Использование COM-технологии при проведении

Экспертизы на соответствие требованием нд тзи / М.Р. Шабан, М.П.

Марковская, Ф.Г. Кислов, А.С. Потенко //Моделювання та

інформаційні технології. — 2015. — Вип. 75. — С. 56-59.

6. Воропаева В.Я. Метод оценки влияния промышленно-

ориентированных программных комплексов на загрузку

информационных систем производственных предприятий // Наукові

праці ДонНТУ. Серія: “Електротехніка і енергетика”. — 2015. —

№1(17). — С. 98-103.

7. Решение на базе DDE [Електронний ресурс] — Режим доступу до

ресурсу: http://www.svaltera.ua/press-center/articles/8773.php

8. Динамический обмен данными (DDE) [Електронний ресурс] — Режим

доступу до ресурсу: https://vunivere.ru/work1279/page2

9. Орфали Р. Основы CORBA / Роберт Орфали, Дан Харки, Джери

Эдвардс. — М.: Горячая Линия - Телеком, Малип, 1999. — 318 с.

Page 52: ДИПЛОМНА РОБОТА - ela.kpi.ua

52

10. Взаимодействие программных компонентов [Електронний ресурс] —

Режим доступу до ресурсу:

https://www.intuit.ru/studies/courses/89/89/lecture/28303? page=3

11. MATLAB Runtime [Електронний ресурс] — Режим доступу до ресурсу:

https://www.mathworks.com/products/compiler/matlab-runtime.html

12. Build standalone applications from MATLAB programs [Електронний

ресурс] — Режим доступу до ресурсу:

https://www.mathworks.com/products/compiler.html

13. Проверка алгоритма и визуализация данных приложения С++ с

использованием команд MatLab [Електронний ресурс] — Режим

доступу до ресурсу: http://5fan.ru/wievjob.php?id=84800

14. Проектування інформаційних систем: Посібник / За ред. В.С.

Пономаренка. — К.: Академія, 2002. — 450 с.

15. Буч Г. Об’єктно-орієнтоване проектування з прикладами застосування

/ Г. Буч. — К.: Академія, 2002. — 723 с.

16. Чудновский М.М. Высокоуровневое программирование и среда matlab.

Подводные камни интеграции / М.М. Чудновский; научный

руководитель к.т.н., доц. Русанова О.А. // Вестник СибГАУ. — 2014.

— №3(55). — С. 162-167.

17. Поддубный // Вестник Томского государственного университета. —

2003. — С. 309-318.

18. Дяконов В.П. MATLAB Полный самоучитель / В.П. Дяконов. — М.:

ДМК Пресс, 2012. — 768 с.

Page 53: ДИПЛОМНА РОБОТА - ela.kpi.ua

53

ДОДАТОК А

Позначення Найменування Примітки

Документація

УКР.НТУУ”КПІ”_ТЕФ_АПЕПС_TВ41348_18Б Записка.docx Текстовачастина

дипломноїроботи

Компоненти

УКР.НТУУ”КПІ”_ТЕФ_АПЕПС_TВ41348_18Б12-1

Scheduler native

Основнийкомпонент

додатку взаємодії MATLAB з C#

УКР.НТУУ”КПІ”_ТЕФ_АПЕПС_TВ41348_18Б12-2

Scheduler Android

Основнийкомпонент

додатку взаємодії C# з MATLAB

Page 54: ДИПЛОМНА РОБОТА - ela.kpi.ua

54

ДОДАТОК Б

package com.mmozhaiskyi.datadb.datastore import com.mmozhaiskyi.datadb.dao.LessonDao import com.mmozhaiskyi.datastore.LessonDataStore import com.mmozhaiskyi.model.Lesson import io.reactivex.Completable import io.reactivex.Single import org.koin.core.KoinComponent import org.koin.core.inject internal class LessonDataStoreImpl : LessonDataStore.Cache, KoinComponent { private val lessonsDao: LessonDao by inject() override fun getLessonsByTeacher(teacherId: String): Single<List<Lesson>> { return lessonsDao.getAllByTeacherId(teacherId) } override fun getLessonsByGroup(groupId: String): Single<List<Lesson>> { return lessonsDao.getAllByGroupId(groupId) } override fun deleteLessonsByTeacher(teacherId: String): Completable { return lessonsDao.getAllByTeacherId(teacherId) .flatMapCompletable { lessons -> lessonsDao.delete(lessons) } } override fun deleteLessonsByGroup(groupId: String): Completable { return lessonsDao.getAllByGroupId(groupId) .flatMapCompletable { lessons -> lessonsDao.delete(lessons) } } override fun saveLessons(lessons: List<Lesson>): Completable { return lessonsDao.insert(lessons) } }

package com.mmozhaiskyi.dataapi.datastore import com.mmozhaiskyi.dataapi.RozkladService import com.mmozhaiskyi.dataapi.util.QueryFormatter import com.mmozhaiskyi.datastore.GroupDataStore import com.mmozhaiskyi.model.Group import io.reactivex.Single import org.koin.core.KoinComponent import org.koin.core.inject internal class GroupDataStoreImpl : GroupDataStore.Remote, KoinComponent { private val service: RozkladService by inject() override fun getGroupsByQuery(query: String): Single<List<Group>> { val q = QueryFormatter.format(query) return service.getGroupsByQuery(q) .map { result ->

Page 55: ДИПЛОМНА РОБОТА - ela.kpi.ua

55

result.data.map { apiModel -> apiModel.toModel() } } } }

package com.mmozhaiskyi.dataapi.datastore import com.mmozhaiskyi.dataapi.RozkladService import com.mmozhaiskyi.dataapi.util.QueryFormatter import com.mmozhaiskyi.datastore.TeacherDataStore import com.mmozhaiskyi.model.Teacher import io.reactivex.Single import org.koin.core.KoinComponent import org.koin.core.inject internal class TeacherDataStoreImpl : TeacherDataStore.Remote, KoinComponent { private val service: RozkladService by inject() override fun getTeachersByQuery(query: String): Single<List<Teacher>> { val q = QueryFormatter.format(query) return service.getTeachersByQuery(q) .map { result -> result.data.map { apiModel -> apiModel.toModel() } } } } package com.mmozhaiskyi.dataapi.model import com.google.gson.annotations.SerializedName import com.mmozhaiskyi.model.Group data class GroupApiModel( @SerializedName("group_id") val id: String, @SerializedName("group_full_name") val name: String, @SerializedName("group_okr") val okr: String, @SerializedName("group_type") val type: String) { fun toModel() = Group(id, name, okr, type) }

package com.mmozhaiskyi.dataapi.model import com.google.gson.annotations.SerializedName import com.mmozhaiskyi.model.Lesson data class LessonApiModel( @SerializedName("lesson_id") val id: String, @SerializedName("day_number") val dayNumber: Short, @SerializedName("day_name") val day: String, @SerializedName("lesson_name") val name: String, @SerializedName("lesson_full_name") val fullName: String, @SerializedName("lesson_number") val lessonNumber: Short, @SerializedName("lesson_type") val type: String, @SerializedName("lesson_week") val weekNumber: Short, @SerializedName("time_start") val timeStart: String, @SerializedName("time_end") val timeEnd: String, @SerializedName("rate") val rate: Int, val teachers: List<TeacherApiModel>?, val groups: List<GroupApiModel>?, val rooms: List<RoomApiModel>?) {

Page 56: ДИПЛОМНА РОБОТА - ela.kpi.ua

56

fun toModel() = Lesson( id, dayNumber, day, name, fullName, lessonNumber, type, weekNumber, timeStart, timeEnd, rate, teachers = teachers?.map { it.toModel() } ?: listOf(), groups = groups?.map { it.toModel() } ?: listOf(), rooms = rooms?.map { it.toModel() } ?: listOf() ) }

package com.mmozhaiskyi.dataapi import com.mmozhaiskyi.dataapi.datastore.GroupDataStoreImpl import com.mmozhaiskyi.dataapi.datastore.LessonDataStoreImpl import com.mmozhaiskyi.dataapi.datastore.TeacherDataStoreImpl import com.mmozhaiskyi.datastore.GroupDataStore import com.mmozhaiskyi.datastore.LessonDataStore import com.mmozhaiskyi.datastore.TeacherDataStore import org.koin.dsl.module import retrofit2.CallAdapter import retrofit2.Converter import retrofit2.Retrofit import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory import retrofit2.converter.gson.GsonConverterFactory object DataApiModule { operator fun invoke() = module { single<GroupDataStore.Remote> { GroupDataStoreImpl() } single<TeacherDataStore.Remote> { TeacherDataStoreImpl() } single<LessonDataStore.Remote> { LessonDataStoreImpl() } single<CallAdapter.Factory> { RxJava2CallAdapterFactory.create() } single<Converter.Factory> { GsonConverterFactory.create() } single<Retrofit> { Retrofit.Builder() .addCallAdapterFactory(get()) .addConverterFactory(get()) .baseUrl(RozkladService.BASE_URL) .build() } single<RozkladService> { get<Retrofit>().create(RozkladService::class.java) } } } package com.mmozhaiskyi.dataapi import com.mmozhaiskyi.dataapi.model.GroupApiModel import com.mmozhaiskyi.dataapi.model.LessonApiModel import com.mmozhaiskyi.dataapi.model.TeacherApiModel import io.reactivex.Single import retrofit2.http.GET

Page 57: ДИПЛОМНА РОБОТА - ela.kpi.ua

57

import retrofit2.http.Path import retrofit2.http.Query internal interface RozkladService { @GET("groups") fun getGroupsByQuery(@Query("search") query: String): Single<GroupsResult> @GET("teachers") fun getTeachersByQuery(@Query("search") query: String): Single<TeachersResult> @GET("groups/{groupId}/lessons") fun getLessonsByGroup(@Path("groupId") groupId: String): Single<LessonsResult> @GET("teachers/{teacherId}/lessons") fun getLessonByTeacher(@Path("teacherId") teacherId: String): Single<LessonsResult> companion object { internal const val BASE_URL = "https://api.rozklad.org.ua/v2/" } } internal data class GroupsResult(val data: List<GroupApiModel>) internal data class TeachersResult(val data: List<TeacherApiModel>) internal data class LessonsResult(val data: List<LessonApiModel>)

package com.mmozhaiskyi.datadb.datastore import com.mmozhaiskyi.datadb.dao.LessonDao import com.mmozhaiskyi.datastore.LessonDataStore import com.mmozhaiskyi.model.Lesson import io.reactivex.Completable import io.reactivex.Single import org.koin.core.KoinComponent import org.koin.core.inject internal class LessonDataStoreImpl : LessonDataStore.Cache, KoinComponent { private val lessonsDao: LessonDao by inject() override fun getLessonsByTeacher(teacherId: String): Single<List<Lesson>> { return lessonsDao.getAllByTeacherId(teacherId) } override fun getLessonsByGroup(groupId: String): Single<List<Lesson>> { return lessonsDao.getAllByGroupId(groupId) } override fun deleteLessonsByTeacher(teacherId: String): Completable { return lessonsDao.getAllByTeacherId(teacherId) .flatMapCompletable { lessons -> lessonsDao.delete(lessons) } } override fun deleteLessonsByGroup(groupId: String): Completable { return lessonsDao.getAllByGroupId(groupId) .flatMapCompletable { lessons -> lessonsDao.delete(lessons) } } override fun saveLessons(lessons: List<Lesson>): Completable {

Page 58: ДИПЛОМНА РОБОТА - ela.kpi.ua

58

return lessonsDao.insert(lessons) } } package com.mmozhaiskyi.datadb.dao import androidx.annotation.VisibleForTesting import com.mmozhaiskyi.datadb.SchedulerQueries import com.mmozhaiskyi.model.Lesson import io.reactivex.Completable import io.reactivex.Single import org.koin.core.KoinComponent import org.koin.core.inject internal class LessonDao : KoinComponent { private val queries: SchedulerQueries by inject() private val groupDao: GroupDao by inject() private val teacherDao: TeacherDao by inject() private val roomDao: RoomDao by inject() fun insert(lessons: List<Lesson>) = Completable .create { e -> try { queries.transaction { lessons.forEach { lesson -> insertSync(lesson) } } e.onComplete() } catch (t: Throwable) { e.onError(t) } } fun delete(lessons: List<Lesson>) = Completable .create { e -> try { queries.transaction { lessons.forEach { lesson -> deleteSync(lesson) } } e.onComplete() } catch (t: Throwable) { e.onError(t) } } fun getAllByGroupId(groupId: String) = Single.create<List<Lesson>> { e -> val q = queries.getLessonsByGroupId("%-$groupId-%") try { val fetched = q.executeAsList() val result = combineFetch(fetched) e.onSuccess(result) } catch (t: Throwable) { e.onError(t) } } fun getAllByTeacherId(teacherId: String) = Single.create<List<Lesson>> { e -> val q = queries.getLessonsByTeacherId("%-$teacherId-%") try { val fetched = q.executeAsList()

Page 59: ДИПЛОМНА РОБОТА - ela.kpi.ua

59

val result = combineFetch(fetched) e.onSuccess(result) } catch (t: Throwable) { e.onError(t) } } @VisibleForTesting fun clear() = Completable.create { e -> try { val clearProcesses = listOf( queries::clearLessons, queries::clearGroups, queries::clearTeachers, queries::clearRooms ) queries.transaction { clearProcesses.forEach { it.invoke() } } e.onComplete() } catch (t: Throwable) { e.onError(t) } } private fun combineFetch(fetched: List<com.mmozhaiskyi.datadb.Lesson>): List<Lesson> { return fetched.map { model -> with(model) { Lesson( id, dayNumber, day, name, fullName, lessonNumber, type, weekNumber, timeStart, timeEnd, rate.toInt(), teacherDao.getAllByIds(model.teachersIds), groupDao.getAllByIds(model.groupsIds), roomDao.getAllByIds(model.roomsIds) ) } } } private fun deleteSync(lesson: Lesson) { queries.deleteLesson(lesson.id) groupDao.deleteSync(lesson.groups.map { it.id }) teacherDao.deleteSync(lesson.teachers.map { it.id }) roomDao.deleteSync(lesson.rooms.map { it.id }) } private fun insertSync(lesson: Lesson) { with(lesson) { queries.insertLesson( id, dayNumber, day, name, fullName,

Page 60: ДИПЛОМНА РОБОТА - ela.kpi.ua

60

lessonNumber, type, weekNumber, timeStart, timeEnd, rate.toLong(), teachers.map { it.id }, groups.map { it.id }, rooms.map { it.id } ) teachers.forEach { teacher -> teacherDao.insertSync(teacher) } groups.forEach { group -> groupDao.insertSync(group) } rooms.forEach { room -> roomDao.insertSync(room) } } } }

package com.mmozhaiskyi.datadb.dao import com.mmozhaiskyi.datadb.SchedulerQueries import com.mmozhaiskyi.model.Room import org.koin.core.KoinComponent import org.koin.core.inject internal class RoomDao : KoinComponent { private val queries: SchedulerQueries by inject() fun insertSync(teacher: Room) { with(teacher) { queries.insertRoom(id, name, latitude, longitude) } } fun deleteSync(ids: List<String>) { queries.deleteRoomByIds(ids) } fun getAllByIds(ids: List<String>): List<Room> { val q = queries.getRoomsByIds(ids, ::Room) return q.executeAsList() } } package com.mmozhaiskyi.datadb.dao import com.mmozhaiskyi.datadb.SchedulerQueries import com.mmozhaiskyi.model.Teacher import org.koin.core.KoinComponent import org.koin.core.inject internal class TeacherDao : KoinComponent { private val queries: SchedulerQueries by inject() fun insertSync(teacher: Teacher) { with(teacher) { queries.insertTeacher(id, name, fullName, shortName, rating) } }

Page 61: ДИПЛОМНА РОБОТА - ela.kpi.ua

61

fun deleteSync(ids: List<String>) { queries.deleteTeacherByIds(ids) } fun getAllByIds(ids: List<String>): List<Teacher> { val q = queries.getTeachersByIds(ids, ::Teacher) return q.executeAsList() } }

package com.mmozhaiskyi.dataapi.datastore import com.mmozhaiskyi.dataapi.RozkladService import com.mmozhaiskyi.datastore.LessonDataStore import com.mmozhaiskyi.model.Lesson import io.reactivex.Single import org.koin.core.KoinComponent import org.koin.core.inject internal class LessonDataStoreImpl : LessonDataStore.Remote, KoinComponent { private val service: RozkladService by inject() override fun getLessonsByTeacher(teacherId: String): Single<List<Lesson>> { return service.getLessonByTeacher(teacherId) .map { result -> result.data.map { it.toModel() } } } override fun getLessonsByGroup(groupId: String): Single<List<Lesson>> { return service.getLessonsByGroup(groupId) .map { result -> result.data.map { it.toModel() } } } }

package com.mmozhaiskyi.dataapi.datastore import com.mmozhaiskyi.dataapi.RozkladService import com.mmozhaiskyi.dataapi.util.QueryFormatter import com.mmozhaiskyi.datastore.GroupDataStore import com.mmozhaiskyi.model.Group import io.reactivex.Single import org.koin.core.KoinComponent import org.koin.core.inject internal class GroupDataStoreImpl : GroupDataStore.Remote, KoinComponent { private val service: RozkladService by inject() override fun getGroupsByQuery(query: String): Single<List<Group>> { val q = QueryFormatter.format(query) return service.getGroupsByQuery(q) .map { result -> result.data.map { apiModel -> apiModel.toModel() } } } }

Page 62: ДИПЛОМНА РОБОТА - ela.kpi.ua

62

package com.mmozhaiskyi.usecase import com.mmozhaiskyi.model.Group import com.mmozhaiskyi.model.Teacher import com.mmozhaiskyi.repository.GroupRepository import com.mmozhaiskyi.repository.TeacherRepository import io.reactivex.Observable import io.reactivex.Single import io.reactivex.functions.BiFunction import org.koin.core.KoinComponent import org.koin.core.inject import java.util.concurrent.TimeUnit sealed class SearchResult { data class TeacherResult(val data: Teacher): SearchResult() data class GroupResult(val data: Group): SearchResult() } class SearchUseCase : KoinComponent { private val groupRepository: GroupRepository by inject() private val teacherRepository: TeacherRepository by inject() fun search(query: Observable<String>): Observable<List<SearchResult>> = query .filter { it.isNotBlank() } .debounce(300, TimeUnit.MILLISECONDS) .switchMapSingle { q -> val zipper = BiFunction { groups: List<Group>, teachers: List<Teacher> -> groups.map(SearchResult::GroupResult) + teachers.map(SearchResult::TeacherResult) } Single.zip( groupRepository.getGroupsByQuery(q), teacherRepository.getTeacherByQuery(q), zipper ) } .onErrorResumeNext(Observable.just(listOf())) }

package com.mmozhaiskyi.repository import com.mmozhaiskyi.datastore.LessonDataStore import com.mmozhaiskyi.model.Lesson import io.reactivex.Single import org.koin.core.KoinComponent import org.koin.core.inject interface LessonRepository { fun getLessonsByGroup(groupId: String): Single<List<Lesson>> fun updateLessonsByGroup(groupId: String): Single<List<Lesson>> fun getLessonsByTeacher(teacherId: String): Single<List<Lesson>> fun updateLessonsByTeacher(teacherId: String): Single<List<Lesson>> } internal class LessonRepositoryImpl : LessonRepository, KoinComponent { private val remote: LessonDataStore.Remote by inject()

Page 63: ДИПЛОМНА РОБОТА - ela.kpi.ua

63

private val cache: LessonDataStore.Cache by inject() override fun getLessonsByGroup(groupId: String): Single<List<Lesson>> { return cache.getLessonsByGroup(groupId) .flatMap { cached -> if (cached.isEmpty()) updateLessonsByGroup(groupId) else Single.just(cached) } } override fun updateLessonsByGroup(groupId: String): Single<List<Lesson>> { return remote.getLessonsByGroup(groupId) .flatMap { fetched -> val clearCache = cache.deleteLessonsByGroup(groupId) val saveToCache = cache.saveLessons(fetched) return@flatMap clearCache .andThen(saveToCache) .andThen(Single.just(fetched)) } } override fun getLessonsByTeacher(teacherId: String): Single<List<Lesson>> { return cache.getLessonsByTeacher(teacherId) .flatMap { cached -> if (cached.isEmpty()) updateLessonsByTeacher(teacherId) else Single.just(cached) } } override fun updateLessonsByTeacher(teacherId: String): Single<List<Lesson>> { return remote.getLessonsByTeacher(teacherId) .flatMap { fetched -> val clearCache = cache.deleteLessonsByTeacher(teacherId) val saveToCache = cache.saveLessons(fetched) return@flatMap clearCache .andThen(saveToCache) .andThen(Single.just(fetched)) } } }

Page 64: ДИПЛОМНА РОБОТА - ela.kpi.ua

64

ДОДАТОК В

При вході в додаток, в першу чергу, з’являється екран авторизації, де

користувач повинен ввести свою групу.

Після цього відкривається головний екран, який містить розклад для

вибраної групи по днях тижня, дату, час та аудиторію.

При натисканні на потрібний предмет з’являється вікно з детальною

інформацією: тип заняття, викладач, аудиторія та розташування на карті. В

цьому вікні також є можливість внесення нотаток з фотографіями.

У вікні «Викладачі» при натисканні на певного викладача, з’являється

його розклад, що по структурі аналогічний до студентського розкладу.


Recommended