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

Найбільш поширеними і застосовними є: метод висхідній розробки і метод низхідній розробки ПС.

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

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

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

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

Малюнок 1.5 - Перший крок формування модульної структури програми при конструктивному підході

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

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

Малюнок 1.6 - Другий етап формування модульної структури програми при конструктивному підході.

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

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

Всі ці методи мають ще різні різновиди в залежності від того, в якій послідовності обходяться вузли (модулі) деревовидної структури програми в процесі її розробки. Це можна робити, наприклад, по верствам (розробляючи все модулі одного рівня, перш ніж переходити до наступного рівня). При низхідній розробці дерево можна обходити також в лексикографічному порядку (зверху вниз, зліва направо). Можливі й інші варіанти обходу дерева. Так, при конструктивній реалізації для обходу дерева програми доцільно слідувати ідеям Фуксмана, які він використовував у запропонованому ним методі вертикального шарування.

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

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

На малюнку 1.7 представлена ​​загальна класифікація розглянутих методів розробки структури програми.

Малюнок 1.7 - Класифікація методів розробки структури програм

Схожі статті