Методи проектування складних програмних систем
Методи проектування ІС поділяють на три основні групи [15, с. 53]:
· метод структурного проектування зверху вниз;
· інформаційне програмування;
· об'єктно-орієнтоване проектування.
Структурний підхід за принципом зверху вниз, відомий під назвою композиційного проектування (composite design), базується на властивостях традиційних мов високого рівня, таких як FORTRAN чи COBOL. У цих мовах основною базовою одиницею декомпозиції є підпрограма, і програма загалом має форму дерева, в якому одні підпрограми в процесі роботи викликають інші підпрограми. Це повністю відповідає структурному проектуванню зверху-вниз, в якому розбиття великої задачі на дрібніші здійснюється за допомогою алгоритмічної декомпозиції.
Значна частина програмного забезпечення була спроектована на основі такого методу. Проте структурний підхід не вирішує проблем, пов'язаних з абстрагуванням даних і приховуванням інформації, а також не забезпечує засобів для організації взаємної сумісності об'єктів. Структурний метод не допускає масштабування для створення дуже складних систем і, як правило, погано поєднується із об'єктними і об'єктно-орієнтованими мовами програмування.
За інформаційного програмування (data-driven design) система розглядається як відображення вхідних даних у вихідні, що безпосередньо впливає на структуру програмного забезпечення. Як і структурне проектування, інформаційне програмування успішно застосовувалося при вирішенні багатьох складних задач, зокрема, для реалізації систем управління інформацією, в яких існують прямі зв'язки між вхідними і вихідними даними системи і не виникають проблеми, пов'язані з швидкодією.
Основний принцип об'єктно-орієнтованого аналізу полягає в тому, що модель системи програмного забезпечення розглядається як сукупність взаємодіючих об'єктів, а кожен об'єкт — як екземпляр певного класу, що входить в певну ієрархію. Об'єктно-орієнтований аналіз і проектування відбиває топологію мов програмування високого рівня, таких якк Smalltalk, Object Pascal, C++, Common Lisp Object System (CLOS), Ada, Eiffel, Python, Visual C# та Java.
Всі методи проектування програмного забезпечення містять наступні компоненти [15, с. 57]:
· умовні позначення — мова опису кожної моделі;
· процес — дії, що дають змогу правильно конструювати моделі;
· інструменти — засоби, що спрощують процес створення моделей, і правила, що дозволяють виявляти помилки в процесі розробки.
Система позначень Unified Modeling Language (UML) — це мова моделювання, яка використовується для аналізу, опису і розробки систем програмного забезпечення ІС. У мові UML існує багато різних діаграм (графічних моделей). Кожна діаграма – це графічна модель системи, яка відбиває певний аспект її властивостей, стану чи поведінки у вигляді структури базових компонентів певного типу та відношень між ними, представлених за допомогою уніфікованих графічних позначень (нотацій).
У об’єктно-орієнтованому моделюванні прийнятий мультимодельний підхід до засобів опису статичних і динамічних властивостей складних систем. Для відображення взаємодії системи з зовнішнім середовищем використовуються моделі прецедентів; для представлення внутрішніх функціональних процесів системи – моделі сценаріїв процесів. Необхідні для реалізації цих моделей концепції були розроблені у двох програмах, які нині є стандартом об’єктно-орієнтованого моделювання: уніфікованій мові моделювання UML та нотації моделей сценаріїв процесів (BPMN). Ці дві моделі, що описують динамічну поведінку складних систем, в UML можуть бути доповнені моделями, які задають логічний і фізичний опис складної системи.
У об’єктно-орієнтованих моделях складних систем (рис. 3.3), так само як і в логіко-алгебраїчних моделях, принциповим є представлення реального світу у вигляді нерозривної сукупності двох рівнів опису – концептуального (абстрактного) та фізичного (матеріального). Сукупність всіх цих взаємоповязаних моделей забезпечує повну специфікацію складної системи.
Рис. 3.3. Система моделей обєктно-орієнтованого моделювання
Синтаксичним засобом створення програмного забезпечення є мови програмування, використання яких на основі певних принципів програмування утворює стиль програмування. Виділяють кілька основних стилів програмування, зокрема:
процедурно-орієнтований, основними абстракціями якого є алгоритми;
об’єктно-орієнтований, основними абстракціями якого є об’єкти і класи;
логіко-орієнтований, заснований на цілях, виражених у термінах числення предикатів;
продукційний, що груптується на правилах «якщо …, то …»;
орієнтований на обмеження, основними абстракціями якого є інваріантні співвідношення.
Доцільність використання стиля програмування залежить від типу і задач ІС: при проектуванні баз знань найзручнішим зазвичай є продукційний стиль, для вирішення обчислювальних задач - процедурно-орієнтований
П.Вегнер [15, с. 60 - 61] виділив чотири покоління найбільш популярних мов програмування високого рівня, поклавши в основу класифікації новаторські мовні конструкції, що вперше з'явилися в цих мовах, Г. Буч продовжив класифікацію ще двома поколіннями, що виникли з 1980 р. до теперішнього часу. Таким чином, можна говорити про шість поколінь мов програмування:
· мови програмування першого покоління (1954-1958) - FORTRAN I, ALGOL-58, Flowmatic, IPL V, основними новими конструкціями яких були математичні формули;
· мови програмування другого покоління (1959-1961) - FORTRAN II (підпрограми, роздільна компіляція); ALGOL-60 (блочна структура, типи даних); COBOL (опис даних, робота з файлами); Lisp (обробка списків, вказівники);
· мови програмування третього покоління (1962-1970) - PL/I (FORTRAN+ALGOL+COBOL ); ALGOL-68, Pascal (розвиток ALGOL-60); Simula (класи, абстракції даних);
· мови програмування четвертого покоління («втрачене покоління»)(1970-1980). У цей період було винайдено багато мов, але лише небагато з них витримали випробування часом, зокрема, С (висока ефектівність, малий розмір виконуваних модулів)
· мови об'єктно-орієнтованого програмування (1980-1990, перевірку часом пройшли лише кілька мов) - Smalltalk 90 (чисто об'єктно-орієнтована мова), C++ (походить від мов С и Simula); Ada83 (суворий контроль типів + риси Pascal;
· інтегровані середовища (з 1990 до нині) - Visual Basic (полегшене проектування графічного користувацького інтерфейсу graphical user interface, GUI для додатків в операційному середовищі Windows); Java (спадкоємець мови Oak для мобільних пристроїв); Python (об'єктно-орієнтована мова сценаріїв); J2EE (інтегроване середовище на базі мови Java для промислового застосування); .NET (інтегроване об'єктно-орієнтоване середовище розробки компанії Microsoft); Visual C# (конкурент мовиа Java для середовища Microsoft .NET); Visual Basic .NET (варіант мови Visual Basic для середовища Microsoft .NET)
Мови програмування різних поколінь відрізняються своєю топологією (topology), під якою розуміють основні конструктивні блоки мови програмування і способи їх взаємозв'язку.
Основним конструктивним блоком в більшості мов першого покоління і ранніх мов другого покоління, таких як FORTRAN та COBOL, є підпрограма (чи параграф, в термінології мови COBOL).
Програми, написані на цих мовах, мають відносно просту структуру, що складається лише з глобальних даних і підпрограм. Глобальні структури даних відкриті для всіх підпрограм і помилка, допущена в одній частині програми, може здійснити руйнівний вплив на решту системи. При внесенні змін до великої системи ці мови не гарантують підтримку цілісності даних. Все це знижує надійність системи і зменшує ясність проектного рішення.
Топологія мов програмування пізнього другого і раннього третього поколінь виявилася варіантом топології їх попередників з підтримкою механізмів передачі параметрів і покращеним керуванням вкладеними підпрограмами. Ця топологія усунула деякі недоліки попередніх мов, зокрема, підсилила контроль над алгоритмічними абстракціями, але все ще не дозволяла створювати великомасштабні системи.
В мові FORTRAN II та інших більш пізніх мовах програмування третього покоління для створення великомасштабних систем був запропонований новий механізм структуризації у вигляді окремого компільованого модуля - довільного контейнеру, що містить набір даних і підпрограм, і дозволяє незалежно розробляти окремі частини однієї і тієї ж програми. Більшість мов цього покоління підтримували певний вид модульної структури, та практично не регламентували семантичне узгодження між інтерфейсами модулів.
Основним конструктивним елементом в об'єктних і об'єктно-орієнтованихмовах є модуль (module), що є логічно зв'язаною сукупністю класів і об'єктів, а не підпрограм. Інакше кажучи, "якщо процедури і функції — це дієслова, а дані — це іменники, то в основі процедурно-орієнтованих програм лежать дієслова, а в основі об'єктно-орієнтованих — іменники" [15, с. 65]. З цієї причини граф структурної моделі малих і середніх за розміром об'єктно-орієнтованих додатків втрачає деревоподібність, характерну для алгоритмічних мов. Крім того, в цих мовах майже або взагалі не використовуються глобальні дані. Дані і операції об'єднуються таким чином, що основними логічними конструктивними елементами об'єктно-орієнтованих систем стають класи і об'єкти, а не алгоритми.
Нині спостерігається великий прогрес в програмуванні великих систем. Перевагою об'єктної моделі є те, що вона допускає масштабування. У крупних системах існують кластери абстракцій, створюючі шари. На кожному рівні абстракції можна виділити сукупності об'єктів, що взаємодіють один з одним для реалізації поведінки, що відноситься до вищого рівня абстракції. Якщо поцікавитися устроєм таких кластерів і заглянути всередину, можна виявити інший набір взаємодіючих абстракцій.
У кожному наступному поколінні мов програмування змінювалися і механізми абстракції. Мови першого покоління використовувалися, в основному, для наукових і технічних обчислень, і словник цієї предметної області був математичним. Такі мови, як FORTRAN I, дозволяли програмістам записувати математичні формули, звільняючи їх від складнощів, пов'язаних з асемблером або машинним кодом. Таким чином, перше покоління мов високого рівня було кроком у напрямі предметної області і відступало від технічних деталей комп'ютерів.
Мови програмування другого покоління перенесли акцент на алгоритмічні абстракції. У той час потужність комп'ютерів збільшувалася, а сфера їх застосування розширювалася, особливо в економічній сфері. Основне завдання полягало в інструктажі машини: наприклад, спочатку прочитати анкети співробітників, потім упорядкувати і після цього роздрукувати| результати на принтері. Мови програмування цього покоління продовжували віддалятися від комп'ютерів і наближатися до предметної області.
У кінці 1960-х років, особливо після винаходу транзисторів і технології інтегральних схем, вартість апаратного забезпечення різко впала, а продуктивність комп'ютерів продовжувала зростати майже експоненціально. Це дозволяло вирішувати ще складніші задачі, але змушувало програмістів маніпулювати різноманітнішими видами даних. В результаті виникли мови третього покоління, такі як ALGOL-68 і Pascal, що підтримують абстракцію даних. Тепер розробники дістали можливість описувати свої власні види даних (тобто створювати призначені для користувача типи) і реалізовувати проектні рішення на мові програмування. Це покоління мов програмування ще більше віддалилося від машинної архітектури і наблизилося до предметної області.
1970-ї роки ознаменувалися бурхливим сплеском активності в області розробки мов програмування. В результаті було створено декілька тисяч різних мов програмування і їх варіантів. Згодом необхідність розробляти все більші програми зробила очевидною неадекватність старих мов. Багато механізмів нових мов програмування розроблялися саме для того, щоб подолати ці обмеження. Лише небагато з цих мов пройшли перевірку часом, проте багато концепцій, втілених у них, було запроваджено в нових версіях попередніх мов.
Найбільший інтерес представляє клас мов, званих об'єктними (object-based) і об'єктно-орієнтованими (object-oriented). Ці мови найкраще підтримують об'єктно-орієнтовану декомпозицію програмного забезпечення. Більшість нових об'єктних мов цієї категорії (і об'єктно-орієнтованих варіантів старих мов програмування) з'явилися в 1980-х і початку 1990-х років. Після 1990-го року з'явилося кілька об'єктно-орієнтованих мов програмування, підтримуваних постачальниками комерційного програмного забезпечення (наприклад, мови Java і C++).
Поява інтегрованих середовищ (наприклад, J2EE і .NET), що надають в розпорядження програмістів величезну кількість компонентів і сервісів, які спрощують вирішення типових і рутинних задач, різко збільшила продуктивність їх праці і продемонструвала переваги повторного використання кодів.