Автор Анна Евкова
Преподаватель который помогает студентам и школьникам в учёбе.

Обзор языков программирования высокого уровня (ЭВОЛЮЦИЯ ТЕХНОЛОГИИ ПРОГРАММИРОВАНИЯ)

Содержание:

ВВЕДЕНИЕ

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

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

  • низкоуровневые – машинно-ориентированные;
  • высокоуровневые – удобные для человеческого восприятия.

Языки высокого уровня также распадаются на несколько категорий:

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

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

Предмет исследования – история возникновения языков, их основные черты и принципы.

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

Для достижения данной цели предстоит решить следующие задачи:

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

1. ЭВОЛЮЦИЯ ТЕХНОЛОГИИ ПРОГРАММИРОВАНИЯ

В настоящее время этап развития общества можно охарактеризовать как «информационный». Этот факт объясняется с информационным взрывом, характеризующимся следующими чертами [1]:

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

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

  • надежность;
  • безопасность;
  • удобство в использовании;
  • проверяемость.

Технологией программирования принято называть комплекс методов и средств, используемых в процессе разработки программного обеспечения. Развитие данной технологии будет рассматриваться в историческом контексте на базе основных этапов развития программирования, как самостоятельной науки [18].

1.1. Стихийное программирование

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

Программа

Рисунок 1 – Структура программы первого этапа развития программирования

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

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

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

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

Также не слишком обнадеживающие результаты показывали и аналитические обзоры и исследования, проводимые в последующие годы по всему миру ведущими аналитиками. Так, результаты исследований компаниеи Standish Group, которая проанализировала работу более трехсот американских корпораций и итоги выполнения более двадцати тысяч проектов, показали, что только 16,2% проектов были выполнены в срок, не выйдя за рамки установленного бюджета и воплотив все функции, оговоренные с заказчиком. Существенно нарушив сроки завершилось 52,7% проектов, при этом расходы на их разработку превысили рамки запланированного бюджета, а оговоренные функции не были реализованы в полном объеме. Полностью аннулированными до завершения оказались 31,1% проектов. Разработчики объяснили данные показатели следующими причинами:

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

Все это можно свести к несовершенству используемой технологии программирования. Разработка программ в то время велась по принципу «снизу-вверх» - сперва разрабатывались простейшие программы, а затем уже предпринимались попытки создать из них более сложную программу. Так большое количество ошибок согласования выявлялось уже на этапе сборки. В конечном счете на процессы отладки и тестирования программ уходило более 80% всего времени разработки. Таким образом, после анализа причин возникновения ошибок, был сформулирован новый подход к программированию, названный структурным [9].

1.2. Структурное программирование

Следующий этап развития технологии программирования приходится на период 60-70-ых гг. прошлого века и опирается на структурный подход. Главной идеей данного подхода является принцип декомпозиции сложных систем с целью последующей реализации в виде отдельных подпрограмм (см. рисунок 2).

Основная программа

1

2

N

Подпрограммы

Рисунок 2 – Структура программы второго этапа развития программирования

Поставленная задача представляется в виде иерархии подзадач простейшей структуры. Проектирование реализуется по принципу «сверху-вниз», который является базовым для процедурных языков программирования, примерами которых являются PL/1, Pascal, C.

Потребность перехода от имеющихся кустарных к принципиально новым способам создания программ, в конце 70-ых годов, объясняется необходимостью контроля процесса разработки программ, прогнозирования и гарантирования стоимости разработки.

Так получил свое развите комплекс инженерных средств и методов создания программного обеспечения, в дальнейшем получивших название «программной инженерии» (software engineering). Впервые данный термин был использован в качестве темы конференции, проводимой НАТО в 1968 г. В Вашингтоне состоялась первая международная конференция, посвященная программной инженерии в 1975 году. Данный период является первым этапом развития программной инженерии как самостоятельной науки. К ней принято относить стандартизацию и систематизацию процессов создания программного обеспечения.

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

Основная программа

Модуль 1

Подпрограммы с локальными данными

 

Модуль k

 

 

Подпрограммы с локальными данными

Модули с локальными данными и подпрограммами

Рисунок 3 – Структура программы, реализующей технологию модульного программирования

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

Подобный подход реализован в разных языках программирования, в качестве примеров могут быть названы новые версии языков C (C++), Pascal, Ada, Modula. С помощью модульного программирования могут разрабатываться надежные программы, размер которых не будет превышать сотни тысяч операторов.

Пропорционально росту объемов программных кодов увеличивалась и сложность межмодульных интерфейсов. Все сложнее становилось обеспечить взаимное влияние отдельных частей программы. Для разработки программ большого объема был предложен объектный подход [10].

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

Объектный подход к программированию – это третий этап (с середины 80‑х до конца 90‑х годов прошлого столетия). Этот этап стал вторым этапом развития программной инженерии, что стало предпосылкой к началу перехода к индустриальному (сборочному) способу разработки программ на базе объектно-ориентированного подхода. Объектно-ориентированным программированием принято называть технологию создания сложных программ, в основе которой лежит представление программы в виде комплекса некоторых объектов, каждый из которых является экземпляром определенного класса, а классы, выстраиваются в некоторую иерархию с наследованием свойств. Взаимодействие программных объектов между собой в такой системе реализуется посредством передачи сообщений (см. рисунок 4).

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

Сообщения

Объект 1

Подпрограммы с локальными данными

Объект 2

Подпрограммы с локальными данными

 

Объект S

 

 

Подпрограммы с локальными данными

Рисунок 4 – Структура программы, реализующей объектно-ориентированный подход

Впервые объектно-ориентированный подход был воплощен в языке имитационного моделирования сложных систем Simula (60-е годы XX в.), затем в специализированном языке моделирования Smalltalk (70-е годы XX в.), а уже позже он нашел свою реализацию в новых версиях универсальных языков программирования, таких, как Pascal, C++, Modula, Java.

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

Использование объектно-ориентированного подхода обладает большим количеством преимуществ, однако его конкретная реализация в языках программирования высокого уровня, таких, как Pascal и C++, имеет серьезные недостатки: так, например, в случае использования этих языков сохраняется зависимость модулей программного обеспечения от адресов экспортируемых свойств и методов, а также форматов и структур данных. В силу того, что отдельные модули должны взаимодействовать между собой, обращаясь к ресурсам - эта зависимость является объективной. Можно попробовать стандартизировать их взаимодействие, хотя связи модулей и не могут быть разорваны, на этой теории и основан компонентный подход к программированию [16].

1.4. Компонентное программирование

Четвертый этап принято называть компонентным подходом и CASE-технологии (с середины 90-х годов ХХ века и нынешнего времени). Идея построения программ из отдельных частей, взаимодействующих между собой посредством стандартизованных двоичных интерфейсов, является фундаментом компонентного подхода. Объекты-компоненты могут собираться в исполняемые файлы или динамически вызываемые библиотеки, передаваться в двоичном виде (без исходных текстов) и применяться в любых языках программирования, поддерживающих соответствующую технологию – это основное отличие от обычных объектов. Особенность современного этапа развития технологии программирования, кроме изменения подхода, заключается во введении в эксплуатацию автоматизированных технологий разработки и сопровождения программного обеспечения, названных CASE-технологиями (Computer-Aided Software/System Engineering – разработка программных систем / программного обеспечения с использованием компьютерной поддержки).

Человеческая память не в способна учитывать все детали, которые должны быть задействованы в процессе разработки программного обеспечения, поэтому в наше время разработка сложных программ без применения средств автоматизации становится практически невозможной. В настоящее время существуют технологии, которые поддерживают как структурный, так и объектный (в том числе и компонентный) подходы к программированию и это CASE-технологии [7].

2. ПРИНЦИПЫ МОДУЛЬНОГО ПРОГРАММИРОВАНИЯ

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

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

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

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

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

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

К достоинствам модульного программирования относятся:

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

Однако есть и ряд недостатков:

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

Однако достоинства модульного программирования настолько велики, что в настояшее время оно является одним из ключевых способов разработки сложных программных систем, не смотря на все отмеченные недостатки [14].

2.2. Характеристики модулей

К основным характеристикам модулей принято относить:

  • рутинность - это показатель независимости модуля от предыстории обращений к нему. Модуль является рутинным, если результат (эффект) обращения к нему характеризуется только значениями его параметров. Если результат (эффект) обращения к нему зависит от внутреннего состояния данного модуля, хранящего следы предыдущих обращений к нему - модуль является зависящим от предыстории. В большинстве случаев использование непредсказуемых модулей не рекомендуется, т.к. они способны провоцировать появление в программах неуловимых ошибок. Однако данная рекомендация не является до конца рациональной, потому что в большинстве случаев именно модуль, зависящий от предыстории, является лучшей реализаций информационно прочного модуля;
  • размер - характеризуется числом операторов (строк), содержащихся в модуле. Модуль не должен быть слишком большим или слишком маленьким. Большое количество маленьких модулей приводит к громоздкой модульной структуре программы и может не окупить накладные расходы, связанные с их оформлением. В то же время большие модули неудобны с точки зрения изучения и внесения изменений, в результате чего они существенно повышают суммарное время повторных трансляций программы при ее отладке. Обычно рекомендуется создавать программные модули размером от нескольких десятков до нескольких сотен операторов[15].

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

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

Модуль

Рисунок 5 – Информационная закрытость модуля

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

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

Таким образом, модуль представляет собой «чёрный ящик», содержимое (реализация) которого недоступно другим модулям, а управление им (интерфейс) наоборот открыто. Любые изменения реализации модуля при этом никак не влияют на его конечных пользователей.

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

  • функциональная связность – отдельные части модуля вместе реализуют одну проблемную задачу (операцию). Например, сюда можно отнести вычисление тангенса угла, расчет заработной платы сотрудника и т.п. Модуль исполняет только ту функцию, для которой он предназначен. Поэтому важно понимать, что модуль вычисления тангенса не должен выводить его значение на экран;
  • информационная связность - выходные данные одной части модуля используются в качестве входных данных другой его части. При этом порядок выполнения действий определен и подобен конвейеру;
  • коммуникативная связность - в данном случае отдельные части модуля связаны по данным. Это говорит о том, что они работают с одним и тем же типом структуры данных, а порядок действий при этом не имеет значения;
  • процедурная связность - данный тип связности относится к ситуации, в которой отдельные части модуля связаны между собой за счет порядка выполняемых ими операций, реализующих некоторый сценарий поведения. При этом зависимость по данным между отдельными частями модуля отсутствует;
  • временная связность - разные части модуля не связаны между собой ни по данным, ни по порядку выполнения, но необходимы в один и тот же период работы системы;
  • логическая связность - в данной ситуации отдельные части модуля объединяются по принципу функционального подобия. Например, модуль состоит из различных функций обработки ошибок. К существенным недостаткам таких модулей принято относить сложное сопряжение с другими модулями, а также большую вероятность внесения ошибок в процессе модификации;
  • связность по совпадению – характеризует ситуацию, при которой в модуле вовсе отсутствуют явно выраженные внутренние связи.

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

  • сцепление по данным - предполагает, что функции одного модуля используют функции второго модуля, при этом все входные и выходные параметры вызываемого модуля представляют собой простые элементы данных;
  • сцепление по образцу – в данной ситуации в качестве параметров используются структуры данных;
  • сцепление по управлению – характеризует ситуацию, в которой один модуль явно управляет работой другого модуля посредством переключателей или флагов, посылая ему управляющие данные;
  • сцепление по внешним ссылкам - в этом случае оба модуля используют ссылки на один и тот же глобальный элемент данных;
  • сцепление по общей области – проявляется в том случае, когда модули разделяют одну и ту же глобальную структуру данных;
  • сцепление по содержанию – описывает ситуацию, в которой один модуль прямо ссылается на содержание другого модуля (в обход интерфейсной части вызываемого модуля) [2].

2.3. Принципы модульного программирования

Принято выделять ряд фундаментальных принципов модульного программирования:

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

При составлении алгоритма очень важно учитывать следующие моменты:

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

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

Функция 1

Функция 2

Модуль 1

Функция 3

Модуль V

Функция 4

Модуль P

Функция 5

Модуль M

Модуль 2

Модуль 3

Модуль K

Модуль N

Модуль P

Модуль Q

Рисунок 6 – Функционально-модульная схема алгоритма

Таким образом можно сделать вывод о том, что принципы модульного программирования по разным параметрам схожи с принципами нисходящего проектирования. Для начала важно определить состав и подчиненность функций. Затем, определить программные модули, отвечающие за реализацию этих функций. Однотипные функции должны быть реализованы одними и теми же модулями. Функция верхнего уровня обеспечивается главным модулем, который управляет исполнением функций всех подчиненных модулей [5].

3. ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ

Основой объектно-ориентированного стиля программирования является объектная модель, построенная на следующих принципах:

  • абстрагирование;
  • инкапсуляция;
  • модульность;
  • иерархия.

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

  • типизация;
  • парллелизм;
  • сохраняемость [17].

3.1. Абстрагирование

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

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

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

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

Определение полного и достаточного набора абстракций в процессе решения любой задачи с использованием ООП является главной целью объектно-ориентированного проектирования.

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

В рамках ООП принято выделять несколько групп абстракций:

  • сущности – объект является моделью некоторой определенной сущности из рассматриваемой предметной области;
  • поведения – объект представляет собой множество операций (действий) реальной сущности;
  • виртуальной машины – объект группирует операции, которые вместе используются более высоким уровнем управления, либо сами применяют некоторый набор операций низкого уровня;
  • прочие – объекты, состоящие из операций, никак не связанных между собой [19].

3.2. Инкапсуляция

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

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

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

Грамотная инкапсуляция позволяет выявить части реализации программной системы, которые могут подвергнуться дальнейшим изменениям. Например, в процессе развития некоторого программного обеспечения, разработчики могут принять решение изменить внутреннее устройство каких-либо объектов с целью повышения показателей производительности или экономии памяти. При этом, важным преимуществом наличия механизмов разграничения доступа (механизмов инкапсуляции), является возможность вне сения изменений в реализацию класса без изменения других классов [4].

3.3. Модульность

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

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

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

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

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

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

Программы, написанные на языке Java, характеризуются более высокой степенью модульной гранулированности по сравнению с C++. Это объясняется тем, что принцип модульности в Java изначально являлся основой модели стандартной библиотеки. Кроме того, Java отличается развитыми средствами поддержки принципа модульности и поощряет разработчиков на активное следование этому принципу.

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

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

3.4. Иерархия

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

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

Таким образом, иерархия — это упорядочение абстракций путем расположения их по уровням.

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

  • структуры классов;
  • структуры объектов.

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

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

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

Если класс имеет несколько родительских классов, такое наследование называется множественным [13].

3.5. Типизация

Абстракция является основой создания понятия типа.

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

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

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

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

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

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

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

И в C++, и в Java имеются средства явного преобразования и проверки типов во время исполнения.

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

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

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

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

Монорфизм представляет собой противоположность полимофризма. Данный принцип характерен для языков с сильной типизацией и статическим связыванием [12].

3.6. Параллелизм

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

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

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

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

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

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

Параллелизм может обеспечиваться не только средствами языка, как это сделано в Java, но и специальными библиотеками, которые используются для разработки параллельных систем на языках, не имеющих встроенной поддержки этого принципа, например в C++ [3].

3.7. Сохраняемость

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

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

В языках программирования традиционно можно встретить под- держку верхних трех уровней этого спектра. Три нижних уровняпринято относить к компетенции баз данных.

Проблема сохраняемости данных связана с проблемой сохранения информации о структуре этих данных, что при сохранении объектов приводит к сохранению классов в объектно-ориентированных базах данных [8].

ЗАКЛЮЧЕНИЕ

В рамках выполнения данной работы была рассмотрена тема «Обзор языков программирования высокого уровня».

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

  • стихийное программирование – разработка программ по принципу «снизу-вверх» - в первую очередь разрабатывались простейшие программы, затем предпринимались попытки собрать из них более сложную программу. При этом в процессе сборки программного продукта обнаруживалось большое число ошибок согласования. В результате на процессы тестирования и отладки программ уходило более 80% всего времени разработки;
  • структурное программирование - разработка программ по принципу «сверху-вниз» - основной идеей данного подхода является принцип декомпозиции сложных систем с целью последующей реализации в виде отдельных подпрограмм. Первоначальная задача представляется в виде иерархии подзадач простейшей структуры;
  • объектно-ориентированное программирование - технология создания сложного программного обеспечения, которая основана на представлении программы в виде совокупности некоторых объектов, каждый из которых представляет собой экземпляр определенного класса, а классы, в свою очередь, образуют иерархию с наследованием свойств;
  • компонентное программирование - в основе данного подхода лежит идея построения программ из отдельно существующих частей программного обеспечения, взаимодействующих друг с другом при помощи стандартизованных двоичных интерфейсов.

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

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

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

В рамках третьей главы приводится подробное рассмотрение основных принципов ООП, а именно:

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

СПИСОК ИСПОЛЬЗОВАННОЙ ЛИТЕРАТУРЫ

  1. Алексеев Е.Р. Программирование на языке C++ / Е.Р. Алексеев, Г.Г. Злобин, Д.А. Костюк, О.В. Чеснокова, А.С. Чмыхало – М.: ALT Linux, 2015. – 448 с.
  2. Богуславский А.А. Основы программирования на языке Си++ / А.А. Богуславский, С.М. Соколов. – Коломна: КГПИ, 2012. – 490 с.
  3. Волкова И.А. Сборник задач и упражнений по языку Си++ / И.А. Волкова, А.А. Вылиток, Л.Е. Карпов. – М.: Изд-во ВМК МГУ им. М.В. Ломоносова, 2013. – 64 с.
  4. Громов Ю.Ю. Технология программирования / Ю.Ю. Громов, О.Г. Иванова, М.П. Беляев, Ю.В. Минин – Тамбов: Изд-во ФГБОУ ВПО «ТГТУ», 2013. – 172 с.
  5. Захарова А.А. Информатика и программирование: программные средства реализации информационных процессов / А.А. Захарова, Е.В. Молнина, Т.Ю. Чернышева. – Томск: Изд-во Томского политехнического университета, 2013. – 318 с.
  6. Иванова Г.С. Технология программирования. – Москва: Изд-во МГТУ им. Н.Э. Баумана, 2012. – 241 с.
  7. Каширина Н.В. Сопоставительный анализ подготовки специалистов по информационным технология в вузах России и за рубежом / Н.В. Каширина, М.М. Маран. – Москва: Изд-во журнала «Науковедение», 2015. – 20 с.
  8. Липачев Е.К. Технология программирования. Базовые конструкции C/C++. – Казань: Изд-во Казан. ун-та, 2012. – 142 с.
  9. Марченко Н.М. Программирования на языке C/C++. – Владивосток: Издательский дом Дальневост. федерал. ун-та, 2013. – 43 с.
  10. Мирошниченко Е.А. Технологии программирования. – Томск: Изд-во ТПУ, 2013. – 124 с.
  11. Мухортов В.В. Объектно-ориентированное программирование, анализ и дизайн / В.В. Мухортов, В.Ю. Рылов. – Новосибирск: ООО «Новософт», 2012. – 108 с.
  12. Поляков А.Ю. Практические задания по дисциплинам «Программирование» и «Языки программирования». – Новосибирск: ФГБОУ ВПО СибГУТИ, 2013. – 4 с.
  13. Сидоров С.Б. Модульное программирование / С.Б. Сидоров, Е.Н. Приблудова. – Нижний Новгород: НГТУ, 2013. – 74 с.
  14. Сикиржицкий А.Ю. Модульное программирование: основные понятия и назначение. – Минск: IV Республиканский научно-практический семинар молодых ученых, 2013. – 4 с.
  15. Соколова Е.А. Технология программирования. – Владикавказ: ФГБОУ ВПО СГТУ, 2013. – 92 с.
  16. Терехов А.Н. Технология программирования. – Москва: Изд-во УИТ, 2016. – 77 с.
  17. Цветкова М.С. Информатика и ИКТ / М.С. Цветкова, Л.С. Великович. – М.: Издательский центр «Академия», 2012. – 352 с.
  18. Цехоня В.И. Технология программирования / В.И. Цехоня, В.Ф. Гузик. – Таганрог: изд-во ТТИ ЮФУ, 2012. – 144 с.
  19. Шаповаленко В.А. Технологии программирования / В.А. Шаповаленко, И.Г. Швайко. – Одесса: Изд-во ОНА им. А.С. Попова, 2012. – 120 с.