Файл: Анализ особенностей применения языков программирования.pdf

ВУЗ: Не указан

Категория: Курсовая работа

Дисциплина: Не указана

Добавлен: 16.05.2023

Просмотров: 435

Скачиваний: 4

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

 Чем же отличается ПП от ООП? Какие преимущества и недостатки они имеют? И, наконец, какой из этих подходов следует изучать начинающему программисту?

 Различия между процедурным и объектно-ориентированным программированием

 Представь: тебе нужно написать небольшую программку, которая запрашивает у пользователя слово, считает количество символов в нем и выводит результат на экран (уже страшно, правда? ;-)).

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

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

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

  • Марка авто
  • Модель авто
  • Мощность двигателя
  • Цвет
  • Год выпуска

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

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

 Какой подход выберет программист в этом случае? Безусловно, объектно-ориентированный. Работа сведется к следующему: создается базовый класс «Техника», в котором будут храниться характеристики, общие и для легковых авто, и для тракторов. Затем создаются два объекта — «Легковой автомобиль» и «Трактор», которые наследуют все характеристики из класса «Техника», а затем дополняются уникальными данными — тем самым «тяговым усилием» и пр.

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


 Преимущества и недостатки процедурного программирования

 Увы, все в этом мире имеет свои минусы и плюсы. Среди недостатков ПП можно назвать следующие: 

  • Риск возникновения множества ошибок при работе над большим проектом. Приходится писать много процедур, и это не может не сказаться на чистоте и работоспособности кода.
  • Все данные процедуры доступны только внутри нее. Их нельзя вызвать из другого места программы и при необходимости придется писать аналогичный код. А это уже противоречит одному из основополагающих принципов программирования, который звучит как Don’t Repeat Yourself (Не повторяйся).
  • Сложность изучения для начинающих. Этот недостаток может кому-то показаться притянутым за уши, но простая статистика свидетельствует, что процедурное программирование для большинства новичков дается сложнее, чем объектно-ориентированное.

 Впрочем, у ПП есть и свои преимущества. Среди них отметим: 

  • Любая процедура (функция) может быть вызвана неограниченное количество раз. Все как в жизни — ты один раз «написал» в голове маршрут к любимой пиццерии, а затем просто вызываешь эту «программу» из памяти.
  • Возможность оперативно решить задачу, в которой отсутствует сложная иерархия. Можно пойти дальше и сказать: если проект не подразумевает создания большого количества классов и объектов, то в ПП совсем нет минусов.

 Преимущества и недостатки объектно-ориентированного программирования 

Главным минусом использования ООП можно назвать громоздкость при решении простых задач. Сравни, например, два участка кода, написанного на PHP. Первый пример — процедурный код, второй — объектно-ориентированный. И тот, и другой скрипт ведут к одному результату: просто выводят на экран фразу «Hello, world»:

 Скрипт №1

<?php

print «Hello, world.»;

?>

 Скрипт №2

<?php

class helloWorld {
function myPrint() {
print «Hello, world.»;
}
}
$myHelloWorld = new helloWorld();
$myHelloWorld->myPrint();

?>

 Показательно, не правда ли?

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

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


 Подводим итоги. Не существует плохого или хорошего ЯП. А вот плохие программисты встречаются, и даже очень часто. Хороший разработчик умеет «помирить» два подхода к программированию в своем сознании и использует оба.

 Помни: язык — это всего лишь инструмент. Он не должен управлять программистом так же, как хвост не может вилять котом. Если же это происходит, то виноват  программист, но не хвост, ведь так?

При реализации того или иного проекта разработчик сам решает, как он будет реализован. Если перед тобой стоит серьезная задача, и ты понимаешь, что без классов и объектов здесь не обойтись — выбирай ОО-язык. К ним относятся Delphi, Java, C#, JavaScript.

 Если же задача довольно проста и ты четко видишь пошаговый алгоритм ее решения, то твоя стихия — это процедурное программирование. К процедурным языкам относятся Basic, Pascal, C.

2.3проблемно-ориентированные языки

В настоящее время вслед за теоретиками в обла­сти информационных технологий (ИТ) многие разработчики программного обеспечения сходятся во мнении, что механизм абстракции является од­ним из ключевых факторов, определяющих каче­ство и эффективность реализации сложного про­граммного продукта. Своего рода «венцом» целого ряда исследований по тематике абстрактных ти­пов данных в 70-х годах прошлого века явился язык CLU, предложенный Барбарой Лисков [1]. Несом­ненна концептуальная значимость языка CLU - он определил одну из основ объектно-ориентирован­ного подхода. В то же время продукт Б. Лисков не получил сколько-нибудь серьезного распростране­ния в среде профессиональных разработчиков, прежде всего, вследствие излишней академичности и перегруженности специфическими конструк­циями.

Достаточно очевидным является то, что разум­но примененный механизм абстракции позволяет весьма эффективно осуществлять командную раз­работку, поддерживая при этом высокое качество программного продукта и эффективное управле­ние процессом. Отложенные вычисления [2-6], модули [2-6], объекты [6, 7], манданты [5, 8] - все это лишь некоторые из современных инструментов введения и поддержки абстракции. Разные языко­вые среды поддерживают эти механизмы в той или иной степени, одни хорошо, другие не очень. Об­щеизвестно, что любые алгоритмические решения могут быть реализованы в рамках различных суще­ствующих парадигм программирования (выбор, в значительной степени, определяется личными предпочтениями). Закономерно возникает вопрос, что же может претендовать на роль «идеального» механизма абстракции при написании приложе­ний, лежит ли он в плоскости технических средств (подобно упомянутому выше CLU) или в большей степени определяется соответствующей методоло­гией, используемой в процессе работы с тради­ционным инструментарием.


Следуя сложившейся традиции [9-11], опреде­лим ПОЯ (DSL — Domain Specific Language) следую­щим образом: язык программирования, который обладает ограниченной степенью выразительно- сти/силы, сфокусированный на определенной предметной области и содержащий конструкты, отражающие абстракции именно этой предметной области.

Проблемно-ориентированные языки принято разделять на три группы [9]:

  1. Внешние (external DSL).
  2. Внутренние (internal DSL).
  3. Инструментальные средства языка (language workbench).

public void insert(User aUser) throws Exception { aUser.setGeneration(O);

getTemplate.update("insert into user_table (id, created, properties, generation, status, backend, email, pswd) values (?,?,?,?,?,?,?,?)”), aUser.getID(), aUser.getCreated(),

Bytes.toByteArray(aUser.getProperties()),

aUser.getGeneration(),

aUser.getStatus().toString(),

aUser.getBackendID(),

aUser.getEmail(),

aUser.getPassword());

}

Рис. 1. Использование внешнего ПОЯ (SQL) из языка Java

Рассмотрим эти группы подробнее.

  1. Внешние ПОЯ используют синтаксис, полно­стью отличный от синтаксиса языка основного приложения. Единственным исключением, пожа­луй, является ситуация, когда в качестве основного языка берется XML. Внешние ПОЯ - это наиболее яркие представители современных инструментов введения абстракции: little languages в Unix, регуляр­ные выражения, SQL, PostScript, awk, HTML и т. д.

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

Еще один существенный недостаток внешних ПОЯ определяется отсутствием у них того, что принято называть «символической интеграцией» (symbolic integration) [12]. Внешний ПОЯ, на самом деле, никак не связан с основным языком прило­жения. Программная среда разработки для базово­го языка, на котором пишется это приложение, не содержит информации о новом ПОЯ, и следова­тельно, проблема редактирования связей испол­няемого кода стоит довольно остро.

Обратимся к примеру, приведенному на рис. 1. Предположим, разработчик решил изменить свой­ства целевого класса User. Во всех современных средах разработки автоматическим переименова- нием/рефакторингом уже никого не удивишь. Од­нако это переименование не будет работать в SQL коде. Это и есть тот самый «символический барьер» между Java и SQL - он не позволяет манипулиро­вать собранной программой как единым целым.


  1. Внутренние ПОЯ используют существующий (обычно - универсальный) язык как свою основу (последний часто называют языком-носителем - host language). При этом создаваемый ПОЯ, как правило, получается синтаксически совместимым с языком-носителем и может быть обработан, ис- пользуя его инфраструктуру (скомпилирован штат­ным компилятором, интерпретирован, отлажен и т. д.). Полученный таким образом ПОЯ является одновременно как расширением языка-носителя, так и его ограничителем.
  2. При построении внутреннего ПОЯ как расши­рения (рис. 2, а), нововведенные концепции стано­вятся доступными для языка-носителя, и оконча­тельным результатом является новый язык, кото­рый обладает полным функционалом исходного языка и добавляет специфичные расширения.ие внутреннего ПОЯ: а) расширение, б) сужение

Рис. 2. Построен

  1. В случае реализации внутреннего ПОЯ как ограничителя языка-носителя (рис. 2, б), новый язык отражает специфику предметной области, при этом скрывая (а зачастую, запрещая) большин­ство конструкций языка-носителя, которые не имеют отношения к задачам данной предметной области. Окончательный результат в таком случае - это также новый язык, только, в некотором смы­сле, суженный.
  2. К классическим примерам внутренних ПОЯ можно отнести: LISP (опытные LTSP-программи­сты говорят о процессе программирования на LISP, как о постоянном создании и использовании новых ПОЯ), Ruby и JRuby (большинство библиотек Ruby выполнены в стиле ПОЯ, как например, Rails) и ряд других языков. Пример использования внутреннего ПОЯ при работе с Ruby приведен на рис. 3.

class XmlBookDetailModel

#implementing IBookDetailModel.java interface include IBookDetailModel

@doc

def initialize {...}

### Methods implementing IBookDetailModel interface ### def getAllBooks {...}

def loadBookDetail(book)

isbn = book.getIsbn

#find matching book by isbn @doc.elements.each("books/book") { |elem| if (elem.attributes['isbn'] == isbn)

book.setTitle(elem.attributes['title']) book.setAuthor(elem.elements['author'].text) book.setPublisher(elem.elements['publisher'].text) book.setDatePublished(elem.elements['datePublished'].text) book.setDescription(elem.elements['description'] .text) return book end

}

return book end end

Рис. 3. Пример использования внутреннего ПОЯ - Ruby

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

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