Бьерн Страуструп - Язык программирования С++. Вступление, глава 1
Страница 18. Модульное программирование


 

1.2.2  Модульное программирование


    Со временем при в проектировании программ акцент сместился с
организации процедур на организацию структур данных. Помимо всего прочего
это вызвано и ростом размеров программ. Модулем обычно называют
совокупность связанных процедур и тех данных, которыми они управляют.
Парадигма программирования приобрела вид:

    Определите, какие модули нужны; поделите программу так, чтобы данные
были скрыты в этих модулях

    Эта парадигма известна также как "принцип сокрытия данных". Если в
языке нет возможности сгруппировать связанные процедуры вместе с данными,
то он плохо поддерживает модульный стиль программирования. Теперь метод
написания "хороших" процедур применяется для отдельных процедур модуля.
Типичный пример модуля - определение стека. Здесь необходимо решить такие
задачи:

    [1] Предоставить пользователю интерфейс для стека (например, функции
push () и pop ()).

    [2] Гарантировать, что представление стека (например, в виде массива
элементов) будет доступно лишь через интерфейс пользователя.

    [3] Обеспечивать инициализацию стека перед первым его использованием.

    Язык Модула-2 прямо поддерживает эту парадигму, тогда как С только
допускает такой стиль. Ниже представлен на С возможный внешний интерфейс
модуля, реализующего стек:


    // описание интерфейса для  модуля,
    // реализующего стек символов:

     void push ( char );
     char pop ();
     const int stack_size = 100;

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

      #include "stack.h"            // используем интерфейс стека

      static char v [ stack_size ]; // ``static'' означает локальный
                                    // в данном файле/модуле
      static char * p = v;           // стек вначале пуст

      void push ( char c )
      {
      //проверить на переполнение и поместить в стек
      }

      char pop ()
      {
      //проверить, не пуст ли стек, и считать из него
      }

    Вполне возможно, что реализация стека может измениться, например, если
использовать для хранения связанный список. Пользователь в любом случае не
имеет непосредственного доступа к реализации: v и p - статические
переменные, т.е. переменные локальные в том модуле (файле), в котором они
описаны. Использовать стек можно так:

      #include "stack.h"       // используем интерфейс стека

      void some_function ()
      {
        push ( 'c' );
        char c = pop ();
        if ( c != 'c' )  error ( "невозможно" );
      }

    Поскольку данные есть единственная вещь, которую хотят скрывать,
понятие упрятывания данных тривиально расширяется до понятия упрятывания
информации, т.е. имен переменных, констант, функций и типов, которые тоже
могут быть локальными в модуле. Хотя С++ и не предназначался специально
для поддержки модульного программирования, классы поддерживают концепцию
модульности ($$5.4.3 и $$5.4.4).  Помимо этого С++, естественно, имеет уже
продемонстрированные возможности модульности, которые есть в С, т.е.
представление модуля как отдельной единицы трансляции.

 
« Предыдущая статья   Следующая статья »