Студопедия

Главная страница Случайная страница

КАТЕГОРИИ:

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Методи розробки структури програми.






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

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

· функціональну специфікацію модуля (опис семантики функцій, виконуваних цим модулем по кожному з його входів).

Функціональна специфікація модуля будується так само, як і функціональна специфікація ПС.

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

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

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



Рис. 7.1. Перший крок формування модульної структури програми при конструктивному підході.


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

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


Рис. 7.2. Другий крок формування модульної структури програми при конструктивному підході.


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

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


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

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

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

Рис. 7.3. Класифікація методів розробки структури програм.


Поделиться с друзьями:

mylektsii.su - Мои Лекции - 2015-2024 год. (0.007 сек.)Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав Пожаловаться на материал