Глава 19 Технологии

И инструменты программирования

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

Краткая история языковлрограммирования

Концепция объектно-ориентированного программирования

19.4. Инструментальные средства и среды разработки программного обе­спечения

Жизненный цикл программного обеспечения

В данной главе рассматриваются языки программирования, методы и средства создания программного обеспечения, а так же практические методики, приме­няемые при разработке ПО; дается определение различным понятиям, связанным с процессом создания программного обеспечения; описываются основные кон­цепции объектно-ориентированного программирования. Особое внимание в главе уделено инструментальным средствам разработки программного обеспечения, а также средствам поддержки жизненного цикла программного обеспечения. Обсуждаются различные модели организации разработки программного обеспе­чения.

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

19.1.1. Основные понятия

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


 

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


 

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


 

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

На рисунке показан приблизительный порядок действий при программирова­нии. Программирование заключается в написании текста (исходного кода) про­граммы на выбранном языке программирования.

Рис. 19.1. Схематичное описание процесса программирования

 

 


 

Для выполнения программы должен быть определенным образом подготовлен объектный модуль — определены адрес его загрузки в оперативную память и адре­са связи с другими объектными модулями. Затем загружается объектный модуль в оперативную память.


 

Объединение модулей объектного кода в единую исполняемую программу яв­ляется результатом работы компоновщика.

Процесс трансляции состоит из нескольких этапов.

1. Производится лексический анализ текста с разбиением его на элементы-лексемы (ключевые слова, имена-идентификаторы и т. д.).

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

3. Исходный код преобразуется в исполняемый машинный код.

Это описание процесса трансляции подводит нас к понятиям, связанным с язы­ками программирования — синтаксису и семантике языка.

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

Пример. Рассмотрим предложение: «Это кошка страус зеленая». В этом примере все используемые в предложении слова и символы допустимы для русского языка, но вместе они составляют недопустимую конструкцию.

 

Формализация описания языка программирования нужна для создания ма­тематической или логической модели работы транслятора, то есть те правила, на основании которых транслятор будет производить синтаксический разбор. Од­ним из известных) способов формального описания синтаксиса языка является метаязык — формы Бэкуса-Наура. Задание синтаксиса языка программирования сводится к перечислению всех его допустимых конструкций.

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

Пример. Рассмотрим предложение: «Зеленая кошка — это страус». Этот пример проходит синтаксическую проверку, поскольку предложение построено правиль­но, но с семантической точки зрения он лишен смысла.

 

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

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

Помимо программы-транслятора, разработка которой основана на формальной

математической модели, можно выделить несколько менее формализованных

требований к языку.

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

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

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

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

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

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

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

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

□ Константа — область памяти, адрес (имя) которой можно использовать для получения хранящегося в ней значения.

□ Инструкция — наименьшая автономная часть языка программирования. Про­грамма представляет собой последовательность инструкций.

□ Подпрограмма — поименованный фрагмент программы, который может быть неоднократно вызван и выполнен в процессе выполнения программы.

□ Функция — подпрограмма, которая может быть использована в выражении.

□ Процедура — любая подпрограмма, не являющаяся функцией.

□ Оператор — специальный вид функции, записываемый в виде символа. Спо­соб записи операторов делает их сходными с математическими операторами,

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

Пример. Оператор + в математике и в языках программирования традиционно обозначает операцию сложения двух операндов. Однако в некоторых языках программирования (например, в Pascal) эту операцию можно выполнять над строками и в случае строковых операндов оператор + реализует конкатенацию (соединение) двух строк в одну.

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

□ Тип данных — относительно устойчивая и независимая совокупность данных, которую можно выделить в рассматриваемом множестве. Есть два базовых типа данных: числовые (бинарные) и символьные. К первому типу данных относятся все виды чисел (целые, дробные, положительные, отрицательные), ко второму — символы и строки. Каждый язык определяет свое множество как числовых, так и символьных данных. Логический тип данных, представляющий собой тип с двумя значениями (true или fal se, 1 или 0), в одних языках выделяется в отдель­ный тип, в других реализуется через числовые типы. Кроме того, могут существо­вать сложные типы данных, состоящие из комбинации простых типов. Деление данных на типы удовлетворяет две потребности: во-первых, каждый тип данных имеет свой размер в памяти. Когда задается переменная определенного типа, то ясно, сколько места нужно выделить для хранения значения этой переменной и как она будет там представлена. Во-вторых, тип данных определяет, какие опе­рации можно производить над этими данными. Например, можно перемножить между собой два числа, но нельзя проделать эту операцию над двумя строками.

19.1.2. Классификация языков программирования

По способу выполнения языки программирования делятся на компилируемые,

интерпретируемые, компилируемые на основе псевдокода и совмещенные.

□ Компилируемые языки. К этой группе относят языки программирования, ис­ходный код которых преобразуется специальной программой-компилятором в объектные модули, которые затем собираются при помощи программы сборки (линковщика) в единый загружаемый модуль. Этот модуль представляет собой выполняемую программу. Компилируемыми являются языки С, С++, Object Pascal.

□ Интерпретируемые языки. К этой группе относят языки программирования, исходный код которых считывается и выполняется специальной программой- интерпретатором инструкция за инструкцией. Интерпретируемыми являются большинство версий языков Basic и Forth.

□ Языки, компилируемые на основе псевдокода («шитого» кода). В этих языках исходный код программы компилируется и выполняется как последователь­ность вызовов подпрограмм из существующих библиотек. Таковыми являются некоторые версии Basic.

□ Совмещенные языки. В совмещенных языках исходный код проходит две стадии обработки. На первой стадии происходит компиляция исходного кода до уровня промежуточного языка (байт-код Bjava или язык MSIL в технологии .NET). На второй стадии происходит интерпретация промежуточного кода (в Java этим занимается виртуальная машина Java) или докомпиляция промежуточного кода до выполняемого машинного кода (эту функцию осуществляет среда вы­полнения CLR в технологии .NET).

По факту созданию процесса языки программирования делятся на создающие процесс и сценарные.

□ Языки, создающие процесс. После запуска программы создается отдельный процесс выполнения этой программы. Так происходит в языках С, С++, Oblect Pascal.

□ Сценарные языки. Сценарий, или скрипт, — это программа, которую выполняет другая программа. В качестве примером можно привести скрипты оболочки в UNIX, программы на языках PHP, Python, Ruby.

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

□ Автономные языки программирования (С, С++, Java) являются автономным инструментом для создания программ.

□ Встроенные языки программирования являются частью какой-то системы и позволяют создавать программы, предназначенные для работы только в этой системе. Пример наиболее известного встроенного языка — VBA (Visual Basic for Application), который используется только внутри приложений Microsoft Office для автоматизации и расширения их функциональности. Встроенными являются также язык программирования системы 1С и язык JavaScript, который выполняется только внутри интернет-приложений.

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

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

□ Языки высокого уровня ближе лингвистически к человеческому языку. Это все остальные языки программирования.

По парадигмам языки программирования делятся на императивные (процедур­ные), функциональные, логические и объектно-ориентированные.

□ Императивные (процедурные) языки описывают решение задачи как последо­вательность процедур. К императивным относится большинство современных языков программирования.

□ Функциональные языки описывают требуемый результат в виде набора вложен­ных друг в друга функций (Haskell).

□ Логические языки описывают требуемый результат в виде суммы логических операций (Prolog).


hO о ^ *

О о> H ю О P

* я s S

4 я -о

^ 5 о § з L

я Я

5 ^

^o о

О fa

S 3 —j —J —J —J —J

О о OOOOO

о со со со со со

P я g *

E о «

о р

2 ю

P P Я I

fa I

P

В'

Я

я я S <ъ

я о fa S

я о н о

hO

tr

я о fa я


о и я п й X S Я Я ° а 5 (D Xl й w E Я О W
<0 ГО
Sc
-S1

S C1; Я н

ь ° л ?

й ОЧ S S

я E ^ р

Ч JU (Т>

CJH Л JU Hffl.,
П) _ я 5
Ф ■о 09 О" Sc О H ш □
■8 © •о SJ § CD Я H я hO о •3 P S S S я P S P E я я я о w E я о> я hO п> Ja о H P S CD Я Я P hO я о
Я CT
хз
H й M (D J=I JU
(D Я (D хз и S (D О Я а нн 3 О •I 5 ^ хз я ju s § JU я я й
£ -о CD

о -

JU

E я

з §

S в

I g

S Il

м о\ я

Я О О

h^ CT

>н Я я

i д О Я ч: О О H - О OxJg
S ш E s Z Z ф * о
W
I] О) S 20
W g рэ Я О Я (D Я хз о M О) ^
s S S

Ф я — [9]

си rj

JU

- хз я Роя

fa а

(Т> (Т> JU

£ 3 з

? fa &3

sSe

а я

s S

P W S4 3
о о я хз о
4 й ju ю S * E ^ Я g 8
JU S S s ж хз 2 о я И Я JU (T) Я н я ^
W HH (Т> 5 » п H CT
H о CT я
SI 5 я
(D я "
. . о Л fa я <<
СО N3
ю

о я

я л

S

JU

о

я о S

Я сг О

к) ■

э *

"О -р

0fi>

П H

"О * M S S *

1 I

Pound; S

S !О

!О СО

S

£

О и

^ о я

Я съ

S § i

S 1

Я ж

w Ss

о S я

3 S

аз

H а

Cr1 «С

S I

S 2

О &

Я %

о я о о и о s о\ Я д CT
JU хз
S о Cr -Ьн К 5
О ^э ХЗ - Я " П) н Я ^3 н ^ я 2 хз ^ о я и E ^э (D Я H я я 9 и о E
о\

я £

§

(D

- fa Я

(D fa О W JU

Я

я

(D

я

я о

J=I

я

о хз

•е-

я

W

о

+

^h я О й CT 2 Os. ^ 2 S о и О я SL Я г- Й Я ^ ^ 2 hO о V Я
я я я JU я о ^ й я я S

+


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

add [ebx+ecx*4+$0d], ah sbb [еах],al add [eax],al mov edx,[esp+$04] jmp -$3c

Рис. 19.3. Фрагмент программы на языке ассемблера

Запомнить, что команда ITlOV означает «переместить», а указанные затем два операнда показывают, откуда нужно взять и куда положить значение, — совсем не трудно.

19.2.2. Второй этап — языки высокого уровня

В языках программирования высокого уровня не требуется знания отдельных машинных команд. Каждая команда в языке программирования высокого уровня скрывает десятки и сотни команд на языке ассемблера, Программисты получа­ют возможность сосредоточиться на алгоритме работы программы, не заботясь об аппаратной реализации компьютера, как было с языками первого поколения. В языках высокого уровня появились средства вызова подпрограмм и создания локальных переменных. В 60-е гг. были созданы такие языки, как ALGOL, Fort­ran, APL.

19.2.3. Третий этап — структурное программирование

Однако программные проекты на языках программирования высокого уровня оставляли желать лучшего: сроки выполнения проектов были очень велики, а ма­териальные издержки выходили за самые пессимистические прогнозы. Наступило время смены уже не языков, а самого подхода к программированию. Программи­рование «снизу вверх», когда вначале разрабатывались подпрограммы, а затем эти подпрограммы объединялись в единое целое при помощи инструкций пере­хода, не оправдало себя. Код получался запутанным, неэкономичным и сложным в отладке. Требовалось изменить саму методологию программирования, вместо программирования «снизу вверх» надо было ввести программирование «сверху вниз», при котором сначала определялись стратегические параметры программного обеспечения, вырабатывался наиболее общий алгоритм работы программы, а затем производилась декомпозиция этого алгоритма до уровня подпрограмм размером в 50-70 строк кода. Далее подпрограммы объединялись в единую программу. Такой подход требовал усовершенствований в самих языках программирования на уровне команд управления ходом выполнения программы. Такие усовершенствования были внесены в языки ALGOL-68, С и Pascal, а сама новая методология получила название структурного программирования.

19.2.4. Четвертый этап — модульное программирование

Порядок, который был наведен с внедрением методологии структурного про­граммирования, был достаточно эффективен, но эта методология не решала про­блемы многократного использования уже разработанного кода. Следующим шагом в развитии языков и методологий программирования было создание модульного программирования. При модульном программировании программа делилась на модули, которые при компиляции образовывали отдельные объектные файлы. Объ­ектные файлы затем собирались в единое целое и получалась исполняемая програм­ма. Появилась возможность объединять фрагменты программы по функциональ­ному признаку. В каждой программе есть код, который уникален только для этой программы, но всегда есть код, применимый при разработке другого программного продукта, например, код, отвечающий за обработку строковых данных. Фрагменты кода, объединенные в модули, можно было использовать многократно в разных программах как в виде исходного кода, так и в виде скомпилированных объектных файлов. Такой подход многократно увеличил скорость разработки программного обеспечения и позволил дополнительно упорядочить сам процесс разработки.

19.2.5. Пятый этап — объектно-ориентированный подход

Алгоритмические языки предыдущих этапов, в основном, обеспечивали реа­лизацию функциональности. При объектно-ориентированном подходе програм­мист должен думать в терминах объектов окружающего мира, нашедших свое абстрактное отражение в сложных типах данных, называемых классами. А языки программирования призваны были давать возможность отображать в коде объек­ты внешнего мира с их свойствами и поведением. Этот этап можно смело назвать революционным по значимости, поскольку все остальные новации в программи­ровании продолжают основываться на принципах объектно-ориентированного программирования (ООП). Яркими представителями языков, поддерживающих ООП, являются С++, Java, Object Pascal и все семейство языков в технологии Mi­crosoft .NET. Именно объектно-ориентированный подход лежит в основе создания средств визуального проектирования и быстрой разработки программ, таких как Borland Delphi, BorlandJBuilder и Microsoft Visual Studio.

19.2.6. Шестой этап — компонентный подход

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

Наиболее известными технологиями, реализующими компонентный подход, являются COM, CORBA и .NET.

19.2.7. Седьмой этап — архитектура, управляемая моделью

Этот этап развития технологий программирования пока еще не достиг своего логического завершения, да и сама идея архитектуры, управляемой моделью (Model Driving Architecture, MDA), продолжает развиваться и совершенствоваться, в част­ности, в рамках технологии ECO для .NET. Смысл технологии MDA — исключить этап кодирования из процесса разработки программного обеспечения. Для того чтобы создать завершенное приложение, достаточно построить его модель на языке UML, а все остальное за вас сделает среда разработки: сгенерирует классы данных, процедуры их обработки, способы подключения к данным, пользовательский ин­терфейс. Хотя это направление развития является весьма многообещающим, на сегодняшний день основным способом создания программного обеспечения все- таки остается ручное кодирование.








Дата добавления: 2016-04-14; просмотров: 642;


Поиск по сайту:

При помощи поиска вы сможете найти нужную вам информацию.

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

Если вам перенёс пользу информационный материал, или помог в учебе – поделитесь этим сайтом с друзьями и знакомыми.
helpiks.org - Хелпикс.Орг - 2014-2024 год. Материал сайта представляется для ознакомительного и учебного использования. | Поддержка
Генерация страницы за: 0.062 сек.