Методы разработки при модульном программировании. Метод восходящей разработки. Метод нисходящей разработки. Конструктивный подход. Архитектурный подход. Нисходящая реализация. Целенаправленная конструктивная реализация.

Урок 21.

Предмет: Технология разработки программных продуктов.

Тема :Основы проектирования программных систем.

 

Цели:

Образовательная

Ознакомление с проектированием программных систем.

Развивающая:

Развивать умение слушать других, делать выводы и обобщать полученные знания

Воспитательная:

Воспитывать чувство значимости предмета в профессиональной деятельности, аккуратности в работе

Межпредметные связи:

-         Английский язык

-         Операционные системы

-         Информационные технологии

-         Основы алгоритмизации и программирования

Оборудование: доска, мел, письменные принадлежности, проектор, ПК

Тип урока: комбинированный

Метод обучения: Объяснительно иллюстративный

Ход урока:

1.Организационный момент

         - Проверка готовности кабинета

         - Объявление темы

2. Постановка цели урока

3.Повторение пройденного материала

       Понятие модуля

      Основные характеристики программного модуля

      Модульная структура программных продуктов

 

4.Сообщение новых знаний

Методы разработки при модульном программировании

    Метод восходящей разработки

    Метод нисходящей разработки

Конструктивный подход

Архитектурный подход

Нисходящая реализация

Целенаправленная конструктивная реализация

 

5. Восприятие и осознание учащимися нового материала

6. Осмысление обобщение и систематизация знаний

7. Подведение итогов урока и  постановка домашнего задания

   Выучить содержимое темы

Гагарина Л.Г.  стр. С.101-107

        Ответить на вопросы:

 

 

 

 

 

Методы разработки при модульном программировании

Спецификация программного модуля состоит из  функциональной спецификации модуля, описывающей семантику  функций, выполняемых этим модулем по каждому из его входов, и

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

спецификация модуля определяется теми же принципами, что и  функциональная спецификация программной системы.

Существуют разные методы разработки модульной структуры Программы, в зависимости от которых определяется порядок программирования и отладки модулей, указанных в этой  структуре. Обычно в литературе обсуждаются два метода [42, 46]:  метод восходящей разработки и метод нисходящей разработки.

 

Метод восходящей разработки

Сначала строится древовидная модульная структура  программы. Затем поочередно проектируются и разрабатываются модули программы, начиная с модулей самого нижнего уровня, затем

предыдущего уровня и т. д. То есть модули реализуются в таком порядке, чтобы для каждого программируемого модуля были уже запрограммированы все модули, к которым он может 

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

Недостатки метода восходящей разработки заключаются в  следующем:

• на нижних уровнях модульной структуры спецификации могут быть еще определены не полностью, что может  привести к полной переработке этих модулей после уточнения

спецификаций на верхнем уровне;

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

• головной модуль проектируется и реализуется в последнюю очередь, что не дает продемонстрировать его заказчику для уточнения спецификаций.

 

Метод нисходящей разработки

Как и в предыдущем методе, сначала строится модульная структура программы в виде дерева. Затем проектируются и реализуются модули программы, начиная с модуля самого  верхнего уровня — головного, далее разрабатываются модули  уровнем ниже и т. д. При этом переход к программированию  какого-либо модуля осуществляется только в том случае, если уже

запрограммирован модуль, который к нему обращается. Затем производится их поочередное тестирование и отладка в таком ^е нисходящем порядке. При таком порядке разработки 

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

тестировании программы. Первым тестируется головной модуль программы, который представляет всю тестируемую программу, при этом все модули, к которым может обращаться головной,

заменяются их имитаторами (так называемыми «заглушками» [45]). Каждый имитатор модуля является простым  программным фрагментом, реализующим сам факт обращения к  данному модулю с необходимой для правильной работы программы обработкой значений его входных параметров и с выдачей, если это необходимо, подходящего результата. Далее производится

тестирование следующих по уровню модулей. Для этого  имитатор выбранного для тестирования модуля заменяется самим  модулем, и добавляются имитаторы модулей, к которым может

обращаться тестируемый модуль. При таком подходе каждый модуль будет тестироваться в «естественных» состояниях  информационной среды, возникающих к моменту обращения к

этому модулю при выполнении тестируемой программы. Таким образом, большой объем «отладочного» программирования  заменяется программированием достаточно простых имитаторов

используемых в программе модулей.

Недостатком нисходящего подхода к программированию  является необходимость абстрагироваться от реальных  возможностей выбранного языка программирования и придумывать  абстрактные операции, которые позже будут реализованы с  помощью модулей. Однако способность к таким абстракциям является необходимым условием разработки больших  программных средств.

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

 

Конструктивный подход

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

Таким образом, на первом шаге разработки программы (при программировании ее головного модуля) формируется верхняя часть дерева, например, как на рис. 3.12.

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

 

 

Архитектурный подход

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

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

реализуются более простые функции, а затем создаются модули, использующие уже имеющиеся функции, и т. д. Это позволяет существенно сократить трудозатраты на разработку конкретной

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

В связи с этим программные модули, создаваемые в рамках  архитектурного подхода, обычно параметризуются для того, чтобы облегчить их применение настройкой параметров.

 

Нисходящая реализация

В классическом методе нисходящей разработки сначала все модули разрабатываемой программы программируются, а затем тестируются в нисходящем порядке. При этом тестирование и

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

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

программированию другого модуля. Такой метод в литературе  получил название метода нисходящей реализации.

 

Целенаправленная конструктивная реализация

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

остальные модули заменяются их имитаторами. Затем к имеющемуся варианту добавляются другие модули, обеспечивающие работу программы для других наборов данных, и так далее до полной

реализации программы. Достоинством этого метода является то, что уже на достаточно ранней стадии создается работающий  вариант разрабатываемой программы. Психологически это играет

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

 

 

 

 

 

 

7.1 Инструментальные средства разработки программ

        Инструментальное программное обеспечение (Software tools) — программное обеспечение, используемое в ходе  разработки, корректировки или развития других программ: 

редакторы, компиляторы, отладчики, вспомогательные системные  программы, графические пакеты и др.

        Сюда входят языки программирования, интегрированные среды разработки программ, CASE-системы и др.

7.1.2 Выбор языка программирования

       Существующие на сегодняшний день языки  программирования можно выделить в следующие группы [1, 56]:

• универсальные языки высокого уровня;

• специализированные языки разработчика программного обеспечения;

• специализированные языки пользователя;

• языки низкого уровня.

      В группе универсальных языков высокого уровня безусловным лидером на сегодня является язык C++. Действительно, он имеет ряд достоинств:

• масштабируемость. На языке C++ разрабатывают  программы для самых различных платформ и систем;

• возможность работы на низком уровне с памятью,  адресами, портами, что при неосторожном использовании может легко превратиться в недостаток;

• C++ имеет мощный препроцессор, унаследованный от С, но, как и любой другой мощный инструмент, требует  осторожного использования;

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

       При этом язык C++ обладает рядом существенных  недостатков:

• подключение интерфейса внешнего модуля через препроцессорную вставку заголовочного файла (#include)  серьезно замедляет компиляцию при подключении большого  количества модулей;

• недостаток информации о типах данных во время  компиляции;

• сложность для изучения и компиляции;

• некоторые преобразования типов неинтуитивны. В  частности, операция над беззнаковым и знаковым числами  выдает беззнаковый результат.

        Для C++ существует большое количество библиотек классов, поддерживающих создание пользовательского интерфейса,  клиент-серверных приложений, работу с базами данных и т. д., 

поэтому пока альтернативы C++ нет [40]. Для второстепенных  проектов иногда используется Visual Basic. Язык Java  рассматривался как альтернатива Basic, но из-за отсутствия визуального средства разработки форм он пока остается малопригодным.  Современный Object Pascal, как и Pascal, предложенный Н. Виртом в середине 70-х годов XX в., остается наиболее привлекательным

для обучения основам программирования в силу своей  простоты, структурированности и обнаружения компилятором  большого количества не только синтаксических, но и семантических

ошибок.

        В нынешнее время в отличие от 60-х годов XX в. языки  программирования создаются крайне редко. За последние 15 лет можно отметить лишь две новинки, получившие широкое  распространение — это Java (Sun Microsystems, 1995 г.), ставший  популярным во многом благодаря технологии его использования в Интернете и появления такого понятия, как виртуальная Java-машина, и С# (Microsoft, 2000 г.), созданный на основе C++.

        Создателем языка является сотрудник Microsoft Андреас Хейлсберг. Он стал известным в мире программистов задолго до того, как пришел в Microsoft. Хейлсберг входил в число ведущих

разработчиков одной из самых популярных сред разработки — Delphi. В Microsoft он участвовал в создании версии Java — J++, так что опыта в написании языков и сред программирования ему

не занимать. Как отмечал сам Андреас Хейлсберг, С# создавался как язык компонентного программирования, и в этом одно из главных достоинств языка, направленное на возможность 

повторного использования созданных компонентов.

       Другие достоинства языка С#:

• сохраняет лучшие черты популярных языков  программирования C/C++, на основе которых он создан. В связи с этим облегчается переход программистов от C++ к С#;

• является проще и надежнее C++. Простота и надежность главным образом связаны с тем, что на С# хотя и  допускаются, но не поощряются такие опасные свойства C++, как указатели, адресация, разыменование, адресная  арифметика;

• является полностью объектно-ориентированным языком, где даже типы, встроенные в язык, представлены классами;

• реализует возможности наследования и универсализации;

• учитывает все возможности Framework .Net, так как С# создавался параллельно с данной средой;

• благодаря каркасу Framework .Net, ставшему надстройкой над операционной системой, программисты С# получают те же преимущества работы с виртуальной машиной, что и

программисты Java. Эффективность кода даже повышается, поскольку исполнительная среда CLR представляет собой компилятор промежуточного языка, в то время как  виртуальная Java-машина является интерпретатором байт-кода;

• мощная библиотека каркаса поддерживает удобство  построения различных типов приложений на С#, позволяя легко строить Web-службы, другие виды компонентов,  достаточно просто сохранять и получать информацию из базы данных и других хранилищ данных;

• является источником надежного и эффективного кода.

         Кроме вышеописанных языков к группе универсальных принадлежат также Modula, Ada, COBOL, FORTRAN и  некоторые другие. Каждый из вышеописанных языков имеет свои  особенности и, соответственно, свою область применения. В настоящее время универсальные языки программирования  применяются в самых различных областях человеческой деятельности, таких как:

• научные вычисления (языки C++, FORTRAN, Java);

• системное программирование (языки C++, Java);

• обработка информации (языки C++, COBOL, Java);

• искусственный интеллект (LISP, Prolog);

• издательская деятельность (Postscript, TeX);

• удаленная обработка информации (Perl, PHP, Java, C++);

• описание документов (HTML, XML).

          С течением времени одни языки развивались, приобретали новые черты и остались востребованными, другие утратили свою актуальность и сегодня представляют в лучшем случае чисто  теоретический интерес (Focal, PL/1 и др.). В значительной степени это связано с такими факторами:

• наличие среды программирования, поддерживающей  разработку приложений на конкретном языке 

программирования;

• удобство сопровождения и тестирования программ;

• стоимость разработки с применением конкретного языка программирования;

• четкость и ортогональность конструкций языка;

• применение объектно-ориентированного подхода.

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

• языки баз данных;

• языки создания сетевых приложений;

• языки создания систем искусственного интеллекта и т. д.

          Специализированные языки пользователя обычно являются  частью профессиональных сред пользователя, характеризуются  узкой направленностью и разработчиками программного 

обеспечения не используются.

        Языки низкого уровня позволяют осуществлять  программирование практически на уровне машинных команд. При этом  получают самые оптимальные как с точки зрения времени 

выполнения, так и с точки зрения объема необходимой памяти  программы. Недостатком их является то, что они не поддерживают принципов структурного программирования [1].

        В настоящее время языки типа ассемблера обычно  используют:

• при написании сравнительно простых программ, для  обращения к техническим средствам, например драйверов;

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

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

 

7.7.3. Выбор среды программирования

       Интегрированной средой разработки программного обеспечения называют систему программных средств, используемую  программистами для разработки программного обеспечения [1, 56].

       Обычно среда разработки включает в себя текстовый  редактор, компилятор и/или интерпретатор, компоновщик, отладчик и справочную систему. Иногда также содержит систему  управления версиями и разнообразные инструменты для упрощения конструирования графического интерфейса пользователя.  Многие современные среды разработки также включают инспектор объектов, браузер классов и диаграмму иерархии классов,  которые используются для объектно-ориентированной разработки ПО. Обычно среда разработки предназначается для одного  определенного языка программирования, как, например, Visual Basic или Deiphi, но существуют среды разработки, предназначенные для нескольких языков, такие как Eclipse или Microsoft Visual Studio.

        Примеры сред разработки — Turbo Pascal, Borland C++, GNU toolchain, DrPython.

        В последнее время, с развитием объектно-ориентированного программирования, широкое распространение получили  упоминавшиеся ранее среды визуального программирования, в 

которых наиболее распространенные блоки программного кода  представлены в виде графических объектов.

         Наиболее часто используемыми являются визуальные среды Delphi, C++ Builder фирмы Borland (Inprise Corporation), Visual C++, Visual Basic фирмы Microsoft, Visual Ada фирмы IBM и др.

244 Глава 7. Разработка программного обеспечения Большую популярность в наши дни получила технология .NET Framework, предложенная фирмой Microsoft в качестве платформы для создания как обычных программ, так и  веб-приложений. Основным преимуществом .NET является 

совместимость различных служб, написанных на разных языках.  Например, служба, написанная на C++ для .NET, может обратиться к методу класса из библиотеки, написанной на Delphi; на С# 

можно написать класс, наследующий от класса, написанного на Visual Basic .NET, а исключение, выброшенное методом,  написанным на С#, может быть поймано и обработано в Delphi.

          Так же как и в случае с выбором языка программирования, выбор среды программирования определяется характером  проекта, привычками и навыками разработчика, веяниями времени, требованиями заказчика и просто общественным мнением: «Все подобные разработки должны выполняться в среде...

 

7.2. Технологии программирования

7.2.1. Объектно-ориентированное программирование

         Рассмотрим сначала, как появилось  объектно-ориентированное программирование. Ключевое понятие, помогающее при  программировании, — это абстракция. Она позволяет лучше понять

сущность программированного объекта или среду. Пусть нужно совершить поездку в Мурманск. Возникают вопросы: «Каким образом это сделать? какой транспорт использовать? сколько это

будет стоить?» и т. д. Нужно выделить главное и отбросить  лишнее. Тут главным будет вид транспорта. Эту абстракцию и проще всего назвать классом при программировании. У транспорта есть данные (скорость, количество двигателей и др.) и методы (взлет, посадка для самолета). Класс группирует данные и методы в единую сущность. Данные обычно закрыты, и их изменение, как

правило, производится посредством методов, т. е. они  защищены корректной работой методов.

           Первое использование классов как объектов произошло в 1967 г.: Бьерн Страуструп применил язык Simula в своей  диссертации для программы, моделирующей компьютерные системы.

Этот язык очень выразителен и позволяет работать с высоким уровнем абстракций. Однако при запуске программы оказалось, что у нее очень низкая производительность и выполнить работу

в срок не удастся, поэтому пришлось переписать программу на языке Си. В Си классов нет. Страуструп их добавил, и появился язык C++ [40]

          Несколько лет назад в журнале Byte появилась статья  «Объектно-ориентированное программирование умерло?». В ней  говорилось о том, что объекты не оправдали возложенные на них надежды. Достичь главной цели — повторного использования кода — с помощью объектов сложно, хотя сам процесс  программирования они упростили.

         В этот же период Microsoft создает Visual Basic. Главным  нововведением в нем является возможность вставки управляющих элементов (кнопок, полей ввода) на форму. К каждому элементу

можно добавить кусок кода для описания его деятельности. 

Оказалось очень удобно, и вскоре были созданы тысячи новых  элементов — появилось расширение VBX (Visual Basic Extention).

Статья Byte описала управляющие элементы VBX как наиболее успешную реализацию мечты о повторном использовании кода.

          У многих поклонников ООП статья вызвала недовольство.

Элементы VBX не являются объектно-ориентированными. В них нет даже концепции метода, нет наследования и полиморфизма.

Тем не менее VBX может рассматриваться как пример  программного компонента. Это часть бинарного кода, который может быть легко вставлен в различные приложения. VBX — это 

любопытная, но тупиковая ветвь эволюции технологии  программирования. Однако она сыграла свою роль.

           Как же развивалась эволюция программирования? 

Первоначально существовали статические библиотеки. Такие библиотеки компоновались в выполняемый файл, т. е. каждая программа  содержала код библиотеки. Их легко представить в виде 

перфокарт, которые вставляли программисты в свои программы в  «далекие времена».

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

Другое полезное свойство DLL — компоновка в процессе  выполнения, т. е. новая версия DLL может быть использована без перестройки приложения. Если новая версия библиотеки 

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

Второй случай называется DLL HELL. Распределение памяти при использовании статических 

библиотек показано на рис. 7.1.

 

7.2.2. Платформа JAVA и .NET

         На данный момент наиболее активно развиваются две  конкурирующие линии технологий создания ПО на основе  компонентов — технологии Java и .NET. Рассмотрим несколько элементов

этих технологий, являющихся ключевыми в создании широко востребованного в настоящее время и достаточно сложного вида приложений. Это Web-приложения, т. е. распределенное  программное обеспечение, использующее базовую инфраструктуру Интернета для связи между различными своими компонентами, а стандартные инструменты для навигации по Web-браузеры —

как основу для своего пользовательского интерфейса.

         Технологии Java представляют собой набор стандартов,  инструментов и библиотек, предназначенных для разработки приложений разных типов и связанных друг с другом использованием языка программирования Java. Торговая марка Java принадлежит

компании Sun Microsystems, и эта компания во многом  определяет развитие технологий Java, но в нем активно участвуют и  другие игроки — IBM, Intel, Oracle, Hewlett-Packard, SAP, Bea и пр.

В этот набор входят следующие основные элементы:

платформа Java Platform Standard Edition (J2SE) [1]. 

Предназначена для разработки обычных, в основном  однопользовательских приложений;

• платформа Java Platform Enterprise Edition (J2EE) [2]. 

Предназначена для разработки распределенных веб-приложений уровня предприятия;

• платформа Java Platform Micro Edition (J2ME) [3]. 

Предназначена для разработки встроенных приложений,  работающих на ограниченных ресурсах, в основном в мобильных телефонах и компьютеризированных бытовых устройствах;

• платформа Java Card [5]. Предназначена для разработки ПО, управляющего функционированием цифровых карт.

Ресурсы, имеющиеся в распоряжении такого ПО,  ограничены в наибольшей степени.

         С некоторыми оговорками можно считать, что J2ME  является подмножеством J2SE, а та, в свою очередь, — подмножеством J2EE. Java Card представляет собой, по существу, особый набор

средств разработки, связанный с остальными платформами  только поддержкой (в сильно урезанном виде) языка Java.

          Язык Java — это объектно-ориентированный язык  программирования, который транслируется не непосредственно в  машинно-зависимый код, а в так называемый байт-код, 

исполняемый специальным интерпретатором, виртуальной Java-машиной (Java Virtual Machine — JVM). Такая организация работы  Java-программ позволяет им быть переносимыми без изменений и 

одинаково работать на разных платформах, если на этих платформах есть реализация JVM, соответствующая опубликованным  спецификациям виртуальной машины.

         Кроме того, интерпретация кода позволяет реализовывать различные политики безопасности для одних и тех же  приложений, выполняемых в разных средах, — к каким ресурсам 

(файлам, устройствам и пр.) приложение может иметь доступ, а к  каким нет, можно определять при запуске виртуальной машины.

Таким способом можно обеспечить запускаемое пользователем вручную приложение (за вред, причиненный которым, будет отвечать этот пользователь) большими правами, чем аплет, 

загруженный автоматически с какого-то сайта в Интернете.

          Режим интерпретации приводит обычно к более низкой  производительности программ по сравнению с программами,  оттранслированными в машинно-специфический код. Для  преодоления этой проблемы JVM может работать в режиме 

динамической компиляции (just-in-time-compilation — JIT), в котором байт-код на лету компилируется в машинно-зависимый, а часто исполняемые участки кода подвергаются дополнительной  оптимизации.

         .NET представляет собой похожий набор стандартов,  инструментов и библиотек, но разработка приложений в рамках .NET возможна с использованием различных языков 

программирования. Основой .NET являются виртуальная машина для промежуточного языка (Intermediate LanguageIL, иногда  встречается сокращение Microsoft IL — MSIL), в который 

транслируются все .NET-программы, также называемая общей средой  выполнения (Common Language RuntimeCLR), и общая  библиотека классов (.NET Framework class library), доступная из всех .NET-приложений.

          Промежуточный язык является полноценным языком  программирования, но он не предназначен для использования людьми. Разработка в рамках .NET ведется на одном из языков, для которых имеется транслятор, в промежуточный язык —Visual Basic.NET, C++, С#, Java (транслятор Java в .NET называется J#, и он не обеспечивает одинаковой работы программ на Java,  оттранслированных в .NET и выполняемых на JVM) и пр. Однако разные языки достаточно сильно отличаются друг от друга, и чтобы гарантировать возможность из одного языка работать с компонентами, написанными на другом языке, необходимо при разработке этих компонентов придерживаться общих правил

(Common Language SpecificationsCLS), определяющих, какими конструкциями можно пользоваться во всех .NET-языках без потери возможности взаимодействия между результатами. 

Наиболее близок к промежуточному языку С# — этот язык был  специально разработан вместе с платформой .NET.

          Некоторым отличием от Java является то, что код на  промежуточном языке в .NET не интерпретируется, а всегда  выполняется в режиме динамической компиляции (ЛТ).

         Компания Microsoft инициировала разработку платформы .NET и принятие стандартов, описывающих ее отдельные элементы (к сожалению, пока не все), и она же является основным

поставщиком реализаций этой платформы и инструментов  разработки. Благодаря наличию стандартов возможна независимая реализация .NET (например, такая реализация разработана в

рамках проекта Mono), но, в силу молодости платформы и  опасений по поводу монопольного влияния Microsoft на ее  дальнейшее развитие, реализации .NET не от Microsoft используются

достаточно редко.

          Для Java-технологий базовым языком является Java, а для изучения правил построения компонентов для .NET  используется язык С#. Он наиболее удобен при работе в этой среде и  наиболее похож на Java.

          Оба языка имеют мощные выразительные возможности  объектно-ориентированных языков последнего поколения,  поддерживающих автоматическое управление памятью и работу в 

многопоточном режиме. Они весьма похожи, но имеют большое число мелких отличий в деталях. Наиболее существенны для  построения программ различия, касающиеся наличия в С# 

невиртуальных методов, возможности объявления и использования пользовательских типов значений и делегатных типов в С# и возможности передачи значений параметров в С# по ссылке.

�м  программным фрагментом, реализующим сам факт обращения к  данному модулю с необходимой для правильной работы программы обработкой значений его входных параметров и с выдачей, если это необходимо, подходящего результата. Далее производится

тестирование следующих по уровню модулей. Для этого  имитатор выбранного для тестирования модуля заменяется самим  модулем, и добавляются имитаторы модулей, к которым может

обращаться тестируемый модуль. При таком подходе каждый модуль будет тестироваться в «естественных» состояниях  информационной среды, возникающих к моменту обращения к

этому модулю при выполнении тестируемой программы. Таким образом, большой объем «отладочного» программирования  заменяется программированием достаточно простых имитаторов

используемых в программе модулей.

Недостатком нисходящего подхода к программированию  является необходимость абстрагироваться от реальных  возможностей выбранного языка программирования и придумывать  абстрактные операции, которые позже будут реализованы с  помощью модулей. Однако способность к таким абстракциям является необходимым условием разработки больших  программных средств.

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

 

Конструктивный подход

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

Таким образом, на первом шаге разработки программы (при программировании ее головного модуля) формируется верхняя часть дерева, например, как на рис. 3.12.

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

 

 

Архитектурный подход

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

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

реализуются более простые функции, а затем создаются модули, использующие уже имеющиеся функции, и т. д. Это позволяет существенно сократить трудозатраты на разработку конкретной

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

В связи с этим программные модули, создаваемые в рамках  архитектурного подхода, обычно параметризуются для того, чтобы облегчить их применение настройкой параметров.

 

Нисходящая реализация

В классическом методе нисходящей разработки сначала все модули разрабатываемой программы программируются, а затем тестируются в нисходящем порядке. При этом тестирование и

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

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

программированию другого модуля. Такой метод в литературе  получил название метода нисходящей реализации.

 

Целенаправленная конструктивная реализация

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

остальные модули заменяются их имитаторами. Затем к имеющемуся варианту добавляются другие модули, обеспечивающие работу программы для других наборов данных, и так далее до полной

реализации программы. Достоинством этого метода является то, что уже на достаточно ранней стадии создается работающий  вариант разрабатываемой программы. Психологически это играет

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