Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
КЛ_Середовище.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
1.07 Mб
Скачать

Міністерство освіти та науки України

Київський національний університет технологій та дизайну

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

Кафедра інформаційних та комп’ютерних технологій

Курс лекцій

з дисципліни

Середовище розробки програм”

для студентів всіх форм навчання

спеціальності 6.091502 “Системне програмування”

Київ-Черкаси 20010

Зміст

1 Об‘єктно-орієнтоване програмування

1.1. Складові класу

1.2 Оголошення класу

2 Огляд палітри компонентів

2.1 Стандартні компоненти

2.2 Сторінки additional та system

3 Обробка виняткових ситуацій у Delphi

3.1 Структурна обробка виняткових ситуацій

3.2 Модель виняткових ситуацій у Delphi

3.2.1 Синтаксис обробки виняткових ситуацій

3.3 Приклади обробки виняткових ситуацій

3.3.1 Виклик виняткової ситуації

3.3.2 Доступ до екземпляра об'єкта exception

 3.4 визначені оброблювачі виняткових ситуацій

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

4 Графічні можливості Delphi

5 Робота з базами данних в Delphi

1 Об‘єктно-орієнтоване програмування

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

У даному визначенні можна виділити три частини: 1) OOP використовує як базові елементи об'єкти, а не алгоритми (ієрархія "бути частиною", що була визначена в главі 1); 2) кожен об'єкт є екземпляром якого-небудь визначеного класу; 3) класи організовані ієрархічно (див. поняття про ієрархію "is а" там же). Програма буде обєктно-орієнтованою тільки при дотриманні всіх трьох зазначених вимог. Зокрема, програмування, не засноване на ієрархічних відносинах, не відноситься до OOP, а називається програмуванням на основі абстрактних типів даних.

Чому програмному забезпеченню притаманна складність?

Складність викликається 5 основними причинами:

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

  • труднощами керування процесом розробки;

  • необхідністю забезпечити достатню гнучкість програми;

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

Складність реального світу. Проблеми, що ми намагаємося вирішити за допомогою програмного забезпечення, часто неминуче містять складні елементи, а до відповідного програмам пред'являється безліч різних, часом взаємовиключних вимог. Розглянемо необхідні характеристики електронної системи багатомоторного літака, стільникової телефонної комутаторної системи і робота. Досить важко зрозуміти, навіть загалом, як працює кожна така система. Тепер додайте до цьому додаткові вимоги (які часто не формулюються явно), такі як зручність, продуктивність, вартість, виживаність і надійність! Складність задачі і породжує складність програмного продукту.

Ця зовнішня складність звичайно виникає через "нестиковку" між користувачами системи і її розроблювачів: користувачі з працею можуть пояснити у формі, зрозумілої розроблювачам, що насправді потрібно зробити. Бувають випадки, коли користувач лише смутно представляє, що йому потрібно від майбутньої програмної системи. Це в основному відбувається не через помилки з тієї чи іншої сторони; просто кожна з груп спеціалізується у своїй області, і їй бракує знань партнера. У користувачів і розроблювачів різні погляди на сутність проблеми, і вони роблять різні висновки про можливі шляхи її рішення. Насправді, навіть якщо користувач точно знає, що йому потрібно, ми важко можемо однозначно зафіксувати всі його вимоги. Звичайно вони відбиті на багатьох сторінках тексту, "розведених" деякими малюнками. Такі документи важко піддаються розумінню, вони відкриті для різних інтерпретацій і часто містять елементи, що відносяться скоріше до дизайну, чим до необхідних вимог розробки.

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

Труднощі керування процесом розробки. Основне завдання розроблювачів полягає в створенні ілюзії простоти, у захисті користувачів від складності описуваного предмета чи процесу. Розмір вихідних текстів програмної системи аж ніяк не входить у число її головних достоїнств, тому ми намагаємося робити вихідні тексти більш компактними, винаходячи хитромудрі і могутні методи, а також використовуючи середовища розробки вже існуючих проектів і програм. Однак нові вимоги для кожної нової системи неминучі, а вони приведуть до необхідності або створювати багато програм "з нуля", або намагатися по-новому використовувати існуючі. Всього 20 років тому програми обсягом у кілька тисяч рядків на ассемблері виходили за межі наших можливостей. Сьогодні звичайними стали програмні системи, розмір яких обчислюється десятками тисяч навіть чи мільйонами рядків на мовах високого рівня. Жодна людина ніколи не зможе цілком зрозуміти таку систему. Навіть якщо ми правильно розкладемо її на складові частини, ми все рівно одержимо сотні, а іноді і тисячі окремих модулів. Тому такий обсяг робіт зажадає залучення команди розроблювачів, в ідеалі як можна меншої по чисельності. Але який би вона не була, завжди будуть виникати значні труднощі, зв'язані з організацією колективної розробки. Чим більше розроблювачів, тим складніше зв'язку між ними і тем складніше координація, особливо якщо учасники робіт географічно видокремлені друг від друга, що типово у випадку дуже великих проектів. Таким чином, при колективному виконанні проекту головною задачею керівництва є підтримка єдності і цілісності розробки.

Гнучкість програмного забезпечення. Будівельна компанія звичайно не має власного лісгоспу, який би їй поставляв ліс для пиломатеріалів; зовсім незвичайно, щоб монтажна фірма спорудила свій завод для виготовлення сталевих балок під майбутній будинок. Однак у програмній індустрії така практика - справа звичайна. Програмування має граничну гнучкість, і розроблювач може сам забезпечити себе всіма необхідними елементами, що відносяться до будь-якого рівня абстракції. Така гнучкість надзвичайно приваблива. Вона змушує розроблювача створювати самотужки всі базові будівельні блоки майбутньої конструкції, з яких складаються елементи більш високих рівнів абстракції. На відміну від будівельної індустрії, де існують єдині стандарти на багато конструктивних елементів і якість матеріалів, у програмній індустрії таких стандартів майже немає. Тому програмні розробки залишаються дуже трудомісткою справою.

Проблема опису поводження великих дискретних систем. Коли ми кидаємо нагору м'яч, ми можемо вірогідно пророчити його траєкторію, тому що знаємо, що в нормальних умовах тут діють відомі фізичні закони. Ми б дуже здивувалися, якби, кинувши м'яч з ледве більшою швидкістю, побачили, що він на середині шляху зненацька зупинився і різко змінив напрямок руху. Навіть прості неперервні системи можуть мати складне поводження через наявність хаосу. Хаос привносить випадковість, що виключає точне прогнозування майбутнього стану системи. Наприклад, знаючи початкове положення двох крапель води в потоці, ми не можемо точно пророчити, на якій відстані друг від друга вони виявляться протягом деякого часу. Хаос виявляється в таких різних системах, як атмосферні процеси, хімічні реакції, біологічні системи і навіть комп'ютерні мережі. На щастя, прихований порядок, очевидно, є у всіх хаотичних системах, у виді так званих аттракторів. У недостатньо налагодженій програмі моделювання польоту м'яча така ситуація легко може виникнути.

Усередині великої прикладної програми можуть існувати сотні і навіть тисячі перемінних і кілька потоків керування. Повний набір цих перемінних, їхній поточних значень, що тече адреси і стека виклику для кожного процесу описує стан прикладної програми в кожен момент часу. Тому що виконання нашої програми здійснюється на цифровому комп'ютері, ми маємо систему з дискретними станами. Аналогові системи, такі, як рух кинутого м'яча, навпроти, є безупинними. Д. Парнас [4] пише: "коли ми говоримо, що система описується безупинною функцією, ми маємо через, що в ній немає схованих сюрпризів. Невеликі зміни вхідних параметрів завжди викликають невеликі зміни вихідних". З іншого боку, дискретні системи по самій своїй природі мають кінцеве число можливих станів, хоча у великих системах це число відповідно до правил комбінаторики дуже велико. Ми намагаємося проектувати системи, розділяючи їх на частині так, щоб одна частина мінімально впливало на іншу. Однак переходи між дискретними станами не можуть моделюватися безупинними функціями. Кожна подія, зовнішнє стосовно програмної системи, може перевести її в новий стан, і, більш того, перехід з одного стану в інше не завжди детермінований. При несприятливих умовах зовнішня подія може порушити поточний стан системи через те, що її творці не змогли передбачити всі можливі варіанти. Уявимо собі пасажирський літак, у якому система керування польотом і система електропостачання об'єднані. Було б дуже неприємно, якби від включення пасажиром, що сидить на місці 38J, індивідуального висвітлення літак негайно ввійшов би в глибоке піку. У безупинних системах таке поводження було б неможливим, але в дискретних системах будь-яка зовнішня подія може вплинути на будь-яку частину внутрішнього стану системи. Це, мабуть, і є головною причиною обов'язкового тестування наших систем; але справа в тім, що за винятком самих тривіальних випадків, усеосяжне тестування таких програм провести неможливо. І поки в нас немає ні математичних інструментів, ні інтелектуальних можливостей для повного моделювання поводження великих дискретних систем, ми повинні задовольнитися розумним рівнем впевненості в їхній правильності.

Наслідок необмеженої складності

"Чим складніше система, тим легше її цілком розвалити". Будівельник навряд чи погодиться розширити фундамент уже побудованого 100-поверхового будинку. Це не просто дорого: робити такі речі значить напрошуватися на неприємності. Але що дивно, користувачі програмних систем, не задумуючись, ставлять подібні задачі перед розроблювачами. Це, затверджують вони, усього лише технічне питання для програмістів.

Наше невміння створювати складні програмні системи виявляється в проектах, що виходять за рамки встановлених термінів і бюджетів і до того ж не відповідають початковим вимогам. Ми часто називаємо це кризою програмного забезпечення, але, чесно говорячи, нездужання, що тягнеться так довго, стає нормою. На жаль, ця криза приводить до розбазарювання людських ресурсів - самого дорогоцінного товару - і до істотного обмеження можливостей створення нових продуктів. Зараз просто не вистачає гарних програмістів, щоб забезпечити всіх користувачів потрібними програмами. Більш того, істотний відсоток персоналу, зайнятого розробками, у будь-якій організації часто повинний займатися супроводом і збереженням застарілих програм. З обліком прямого і непрямого внеску індустрії програмного забезпечення в розвиток економіки більшості ведучих країн, не можна дозволити, щоб існуюча ситуація залишилася без змін.

Канонічна форма складної системи. Виявлення загальних абстракцій і механізмів значно полегшує розуміння складних систем. Наприклад, досвідчений пілот, зорієнтувавшись усього за кілька хвилин, може взяти на себе керування багатомоторним реактивним літаком, на якому він раніш ніколи не літав, і спокійно його вести. Визначивши елементи, загальні для всіх подібних літаків (такі, як кермо керування, елерони і дросельний клапан), пілот потім знайде відмінності цього конкретного літака від інших. Якщо пілот уже знає, як керувати одним літаком визначеного типу, йому набагато легше навчитися керувати іншим схожим літаком.

Цей приклад наводить на думку, що ми зверталися з терміном ієрархія в дуже приблизному змісті. Найбільш цікаві складні системи містять багато різних ієрархій. У літаку, наприклад, можна виділити кілька систем: харчування, керування польотом і т.д. Така розбивка дає структурну ієрархію типу "бути частиною". Цю же систему можна розкласти зовсім іншим способом. Наприклад, турбореактивний двигун - особливий тип реактивного двигуна, a "Pratt and Whitney TF30" - особливий тип турбореактивного двигуна. З іншого боку, поняття "реактивний двигун" узагальнює властивості, властивим усім реактивним двигунам; "турбореактивний двигун" - це просто особливий тип реактивного двигуна з властивостями, що відрізняють його, наприклад, від прямоточного.

Ця друга ієрархія являє собою ієрархію типу "is-a". Виходячи з нашого досвіду, ми визнали за необхідне розглянути систему з двох точок зору, як ієрархію першого і другого типу. назвемо ці ієрархії відповідно структурою класів і структурою об'єктів.

Поєднуючи поняття структури класів і структури об'єктів з п'ятьма ознаками складних систем, ми приходимо до того, що фактично всі складні системи можна представити однієї і тієї ж (канонічної) формою. Тут приведені дві ортогональних ієрархії однієї системи: класів і об'єктів. Кожна ієрархія є багаторівневою, причому в ній класи й об'єкти більш високого рівня побудовані з більш простих. Який клас чи об'єкт обраний у якості елементарного, залежить від розглянутої задачі. Об'єкти одного рівня мають чітко виражені зв'язки, особливо це стосується компонентів структури об'єктів. Усередині будь-якого розглянутого рівня знаходиться наступний рівень складності. Відзначимо також, що структури класів і об'єктів не є незалежними: кожен елемент структури об'єктів представляє специфічний екземпляр визначеного класу. Як видно з мал. 1-1, об'єктів у складній системі звичайно набагато більше, ніж класів. Показуючи обидві ієрархії, ми демонструємо надмірність розглянутої системи. Якби ми не знали структуру класів нашої системи, нам довелося б повторювати ті самі зведення для кожного екземпляра класу. З уведенням структури класів ми розміщаємо в ній загальні властивості екземплярів.

Структури класів і об'єктів системи разом ми називаємо архітектурою системи.

Алгоритмічна декомпозиція. Більшість з нас формально навчено структурному проектуванню "зверху вниз", і ми сприймаємо декомпозицію як звичайний поділ алгоритмів, де кожен модуль системи виконує один з етапів загального процесу.

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

Хоча обидві схеми вирішують ту саму задачу, але вони роблять це різними способами. В другій декомпозиції світ представлений сукупністю автономних діючих осіб, що взаємодіють один з одним, щоб забезпечити поводження системи, що відповідає більш високому рівню. Таким чином, кожен об'єкт володіє своїм власним поводженням, і кожний з них моделює деякий об'єкт реального світу. З цього погляду об'єкт є цілком відчутною річчю, що демонструє цілком визначене поводження. Об'єкти щось роблять, і ми можемо, пославши їм повідомлення, попросити їх виконати те й те. Тому що наша декомпозиція заснована на об'єктах, а не на алгоритмах, ми називаємо її обєктно-ориєнтованою декомпозицією.

ООП пропонує новий підхід до розробки програмного забезпечення призначеного для рішення задач підвищеної складності.

Звичайно на мовах ООП пишуть складні системи, що включають у себе різні рівні абстракції. Фундаментальна концепція ООП складається в передачі повідомлень об'єктів. Для цього необхідно щоб об'єкти визначалися разом з повідомленнями, на які вони будуть реагувати (у процедурах мов програмування визначалися спочатку функції, потім дані, що будуть їм передаватися).

Існують 5 компонент ООП:

  1. Об'єкт;

  2. Повідомлення;

  3. Клас;

  4. Спадкування;

  5. Метод.

Визначення кожного з компонентів містить у собі визначення інших, тобто всі ці компоненти тісно зв'язані один з одним.

ОО мови програмування повинні мати властивості:

  • абстракції;

  • інкапсуляції;

  • спадкування;

  • поліморфізму.

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

Об'єкт являє собою інкапсульовану абстракцію, що відображає його внутрішній стан.

Спосіб яким об'єкт обробляє повідомлення, залежить не тільки від повідомлення, але і від стану самого об'єкта, ця властивість у ООМ реалізовано поліморфізмом.

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

Опис кожного методу унікально.

Приклади ОО мов програмування:

Сама несуперечлива ООМ Small Talk (він практично не використовується), Clos, C++, ADA, Delphi, ...

Кроки програмування при написанні великої системи.

  1. Вивчення предметної області і визначення основних об'єктів для рішення даної задачі;

  2. Визначення закритого даного, даного стану для цих об'єктів;

  3. Визначення другорядних об'єктів і їхніх захищених даних;

  4. Розробка ієрархії класів, що представляють об'єкти;

  5. Ідентифікація ключових повідомлень, що повинні обробляти об'єкти кожного класу;

  6. Розробка початкової послідовності виражень, що представляють рішення проблеми на високому рівні;

  7. Розробка методів, що обробляють усі повідомлення;

  8. Очищення проекту.

Класи - це особливий “винахід” програмістів для спрощення розробки складних програм і поліпшення їхньої якості. В основі класів лежать три фундаментальних принципи, що називаються інкапсуляція, спадкування і поліморфізм.

Інкапсуляція

Клас являє собою єдність трьох сутностей - полів, методів і властивостей. Об'єднання цих сутностей у єдине ціле і називається інкапсуляцією. Інкапсуляція дозволяє багато в чому ізолювати клас від інших частин програми, зробити його “самодостатнім” для рішення конкретної задачі. У результаті клас завжди несе в собі деяку функціональність. Наприклад, клас ТForm містить (інкапсулює в собі) усе необхідне для створення Windows-вікна, клас TMemo являє собою полнофункціональний текстовий редактор, клас TTimer забезпечує роботу програми з таймером і т.д.

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

Спадкування

Любою клас може бути породжений від іншого класу. Для цього при його оголошенні вказується ім'я класу-батька:

TChildClass = class (TParentClass)

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

Усі класи Object Pascal породжені від єдиного батька класу TObject. Цей клас не має полів і властивостей, але містить у собі методи самого загального призначення, що забезпечують весь життєвий цикл будь-яких об'єктів - від їхнього створення до знищення. Програміст не може створити клас, що не був би дочірнім класом TObject. Наступні два оголошення ідентичні:

TaClass = class(TObject) TaClass = class

Принцип спадкування приводить до створення дерева класів, що поступово розростається при переміщенні від TObject до його нащадків. Кожен нащадок доповнює можливості свого батька новими і передає їх своїм нащадкам.

Для приклада клас Tpersistent збагачує можливості свого батька TObject: він “уміє” зберігати дані у файлі й одержувати їх з нього, у результаті це вміють робити і весь його нащадки. Клас TComponent, у свою чергу, уміє взаємодіяти із середовищем розроблювача і передає це уміння своїм нащадкам. Tcontrol не тільки здатний працювати з файлами і середовищем розроблювача, але він ще вміє створювати й обслуговувати видимі на екрані зображення, а його нащадок TWinControi може створювати Windows-вікна і т.д.

Рис. 9.1. Фрагмент дерева класів Object Pascal

Поліморфізм

Поліморфізм - це властивість класів вирішувати схожі за змістом проблеми різними способами. У рамках Object Pascal поведінкові властивості класу визначаються набором вхідних у нього методів. Змінюючи алгоритм того чи іншого методу в нащадках класу, програміст може додавати цим нащадкам відсутні в батька специфічні властивості. Для зміни методу необхідно перекрити його в нащадку, тобто оголосити в нащадку однойменний метод і реалізувати в ньому потрібні дії. У результаті в об'єкті-батьку й об'єкті-нащадку будуть діяти два однойменних методи, що мають різну алгоритмічну основу і, отже, що додають об'єктам різні властивості. Це і називається поліморфізмом об'єктів.

У Object Pascal поліморфізм досягається не тільки описаним вище механізмом спадкування і перекриття методів батька, але і їх віртуалізацією, що дозволяє батьківським методам звертатися до методів своїх нащадків.