Технологія структурного програмування

3.2.1. Поняття структурного програмування

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

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

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

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

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

  • підвищення продуктивності праці програмістів при написанні та контролі програм;
  • отримання програм, які більш придатні для супроводу, оскільки складаються з окремих модулів;
  • створення програм колективом розробників;
  • закінчення створення програм у заданий термін.

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

3.2.2. Методи структурного програмування

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

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

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

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

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

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

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

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

3.2.3. Модульне програмування

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

Необхідно розрізняти використання слова модуль, коли йдеться про одиницю дроблення великої програми на окремі блоки (які можуть бути реалізовані у вигляді процедур і функцій) і коли мається на увазі синтаксична конструкція мов програмування (unit в Object Pascal).

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

Концепцію модульного програмування можна сформулювати у вигляді таких понять і положень:

  1. великі завдання розбиваються на ряд більш дрібних, функціонально самостійних підзадач - модулів, які пов'язані між собою тільки вхідними і вихідними даними;
  2. модуль являє собою "чорний ящик" з одним входом і одним виходом. Це дозволяє безболісно проводити модернізацію програми в процесі її експлуатації, полегшує її супровід, а також дозволяє розробляти частини програмного проекту різними мовами програмування;
  3. у кожному модулі повинні здійснюватися ясні завдання. Якщо призначення модуля незрозуміле, то це означає, що декомпозицію на модулі було проведено недостатньо якісно. Процес декомпозиції потрібно продовжувати до тих пір, поки не буде чіткого розуміння призначення усіх модулів та їх оптимального поєднання;
  4. вихідний текст модуля повинен мати заголовок та інтерфейсну частину, де відображаються призначення модуля й усі його зовнішні зв'язки;
  5. у ході розробки модулів програми слід передбачати спеціальні блоки операцій, що враховують реакцію на можливі помилки в даних або в діях користувача.

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

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