Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

PrIS

.pdf
Скачиваний:
45
Добавлен:
07.12.2018
Размер:
7.24 Mб
Скачать

21

1.1. Складність програмного забезпечення

Складність програмного забезпечення − зовсім не випадкова її властивість. Складність виникає з чотирьох основних причин:

складністю реальної ПО, з якої виходить замовлення на розроблення програмного забезпечення (ПЗ);

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

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

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

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

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

́

кожна така система. Тепер доповніть це додатковими вимогами (часто не формульованими явно), такі як зручність, продуктивність, вартість, виживаність і надійність! Складність завдання і породжує складність програмного продукту.

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

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

22

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

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

під супроводом розуміється усунення помилок;

під еволюцією − внесення змін до системи у відповідь на вимоги до неї, що змінилися;

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

що розпадається на частини.

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

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

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

23

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

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

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

24

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

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

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

Як ми можемо змінити цей стан? Оскільки проблема виникає через складності структури програмних продуктів, ми пропонуємо спочатку розглянути способи роботи зі складними структурами в інших областях. Насправді, можна навести безліч прикладів складних систем, які успішно функціонують. Деякі з них створені людиною, наприклад: космічний човник Space Shuttle, тунель під Ла-Маншем, великі фірми типу Microsoft або General Electric. У природі існують ще складніші системи, наприклад система кровообігу людини або рослина.

25

1.2. Структура складних систем

1.2.1. Приклади складних систем

Структура персонального комп'ютера. Персональний комп'ютер

(ПК) – прилад помірної складності. Більшість ПК складаються з одних і тих самих основних елементів: системної плати, монітора, клавіатури і пристрою зовнішньої пам'яті якого-небудь типу (гнучкого або жорсткого диска). Ми можемо взяти будь-яку з цих частин і розкласти її, своєю чергою, на складові. Системна плата, наприклад, містить оперативну пам'ять, центральний процесор (ЦП) і шину, до якої підключені периферійні пристрої. Кожну з цих частин можна також розкласти на складові: ЦП складається з реґістрів і схем керування, які самі складаються зі ще простіших деталей: діодів, транзисторів і ін.

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

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

Структура рослин і тварин. Ботанік намагається зрозуміти схожість і відмінності рослин, вивчаючи їх морфологію, тобто форму і структуру. Рослини – це складні багатоклітинні організми. В результаті спільної діяльності різних органів рослин відбуваються такі складні типи поведінки, як фотосинтез і всмоктування вологи.

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

26

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

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

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

У комп'ютері транзистори використовуються як у схемі ЦП, так і жорсткого диска. Аналогічно, велика кількість "уніфікованих елементів" є у всіх частинах рослини. Наприклад, клітини служать основними будівельними блоками всіх структур рослини; коріння, стебла і листя рослини складаються з клітин. І хоча будь-який із цих вихідних елементів дійсно є клітиною, існує величезна кількість всіляких клітин. Є клітини, що містять і не містять хлоропласт, клітини з оболонкою, проникною і непроникною для води, і навіть живі і мертві клітини.

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

Звернемося до зоології. Багатоклітинні тварини, як і рослини, мають ієрархічну структуру: клітини формують тканини, тканини працюють разом як органи, групи органів визначають систему (наприклад, травну) і так далі. Основний будівельний блок всіх рослин і тварин – клітина. Природно, між клітинами рослин і тварин існують відмінності. Клітини рослини, наприклад, поміщені в жорстку целюлозну оболонку на відміну від клітин тварин. Але, незважаючи на ці відмінності, обидві вказані структури, поза сумнівом, є клітинами. Це приклад узагальненості в різних сферах.

27

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

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

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

Структура соціальних інститутів. Як останній приклад складних систем розглянемо структуру суспільних інститутів. Люди об'єднуються в групи для вирішення завдань, які не можуть бути вирішені індивідуально. Одні організації швидко розпадаються, інші функціонують впродовж декількох поколінь. Чим більша організація, тим виразніше виявляється в ній ієрархічна структура. Транснаціональні корпорації складаються з компаній, які, своєю чергою, складаються з відділень, що містять різні філії. Останнім належать вже окремі офіси і так далі. Межі між частинами організації можуть змінюватися, і з часом може виникнути нова, стабільніша ієрархія.

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

1.2.2. П'ять ознак складної системи

28

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

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

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

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

Що ж треба вважати простими елементами системи? Досвід підказує нам відповідь.

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

Нижчий рівень для одного спостерігача може виявитися досить високим для іншого.

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

3.Внутрішньокомпонентний зв'язок зазвичай сильніший, ніж зв'язок між компонентами. Ця обставина дозволяє відділяти "високочастотні" взаємодії всередині компонентів від "низькочастотної" динаміки взаємодії між компонентами.

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

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

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

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

29

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

5. Будь-яка складна система, що працює, є результатом розвитку простішої системи, яка працює... Складна система, спроектована "з нуля", ніколи не запрацює. Треба починати з простої системи, яка працює.

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

1.2.3. Організована і неорганізована складність

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

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

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

30

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

Об'єднуючи поняття структури класів і структури об'єктів з п'ятьма ознаками складних систем, ми приходимо до того, що фактично всі складні системи можна подати однією і тією самою (канонічною) формою, яка показана на рис. 1.1.

 

 

 

 

Об’єкти

 

 

 

и

D1

 

 

 

 

 

 

с

 

 

а

 

 

л

 

 

 

К

 

 

C1

 

 

 

 

 

 

 

 

 

D3

 

 

 

C2

C3

 

 

 

 

D2

 

 

 

 

D4

 

 

 

C4

 

 

 

 

 

D6

 

 

 

C5

D5

 

 

 

 

D7

 

 

 

C6

C7

 

 

 

 

D8

Рис. 1.1. Канонічна форма складної системи.

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