Chevroletavtoliga - Автомобильный портал

Объектно-ориентированное программирование. Программирование Язык описания интерфейсов

8.2. ВВЕДЕНИЕ В ОБЪЕКТНО-ОРИЕНТИРОВАННЫЙ ПОДХОД К РАЗРАБОТКЕ ПРОГРАММ

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

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

Модуль ООПр - файл описаний объектов и действий над ними.

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

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

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

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

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

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

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

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

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

Покупатель билета не может положить деньги непосредственно в отсек кассового аппарата или сейф кассира, а также самостоятельно отсчитать себе сдачу. Таким образом, кассир как бы заключен в оболочку, или капсулу, которая отделяет его и покупателя от лишних взаимодействий. Помещение кассы (капсула) имеет особое устройство, исключающее доступ покупателей билетов к деньгам. Это и есть инкапсуляция объектов, позволяющая использовать только допустимый интерфейс - обмен информацией и предметами только посредством допустимых сообщений, а может быть, еще и подаваемых в нужной последовательности. Именно только через вызов сообщениями особых методов осуществляется обмен данных, отделяя покупателей от полей. Благодаря инкапсуляции покупатель может лишь отдавать в качестве оплаты деньги за билет в форме сообщения с аргументом "сумма". Аналогично, но в обратном направлении кассир возвращает сдачу.

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

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

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

Фундаментальной концепцией в объектно-ориентированном программировании является понятие классов. Все объекты являются представителями, или экземплярами, классов. Например: у вас наверняка есть примерное представление о реакции кассира на запрос о заказе билетов, поскольку вы имеете общую информацию о людях данной профессии (например, кассире кинотеатра) и ожидаете, что он, будучи представителем данной категории, в общих чертах будет соответствовать шаблону. То же самое можно сказать и о представителях других профессий, что позволяет разделить человеческое общество на определенные категории по профессиональному признаку (на классы). Каждая категория в свою очередь делится на представителей этой категории. Таким образом, человеческое общество представляется в виде иерархической структуры с наследованием свойств классов объектов всех категорий. В корне такой классификации может находиться класс "HomoSapience" или даже класс "млекопитающие" (рис. 8.1).

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

Классы могут быть организованы в иерархическую структуру с наследованием свойств. Класс-потомок наследует атрибуты родительского класса, расположенного ниже в иерархическом дереве (если дерево иерархии наследования растет вверх). Абстрактный родительский класс - это класс, не имеющий экземпляров объектов. Он используется только для порождения потомков. Класс "HomoSapience", скорее всего, будет абстрактным, поскольку для практического применения, например работодателю, экземпляры его объектов не интересны.

Рис. 8.1. Понятие создания объекта как экземпляра класса ПТИЦЫ

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

От класса "кассир железнодорожной кассы" могут быть получены экземпляры объектов: "кассир кассы № 1", "кассир кассы № 2", "кассир кассы № 3" и т. д.

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

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

Пусть, согласно произведенной классификации, объекты "скрипач с фамилией Петров" и "водитель автомобиля Сидоров" будут экземплярами разных классов. Для того чтобы получить объект "Иванов, являющийся одновременно скрипачом и водителем", необходим особый класс, который может быть получен из классов "скрипач" и "водитель автомобиля" множественным наследованием (рис. 8.3). Теперь работодатель, послав особое сообщение делегирования, может поручить (делегировать) объекту "Иванов" выполнять функцию либо водителя, либо скрипача. Объект "Иванов", находящийся за рулем автомобиля, не должен начать играть на скрипке. Для этого должен быть реализован механизм самоделегирования полномочий - объект "Иванов", находясь за рулем, запрещает сам себе игру на скрипке. Таким образом, понятие обязанности или ответственности за выполнение действия является фундаментальным в объектно-ориентированном программировании.

Рис. 8.3. Пример простого и множественного наследования

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

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

Агрегированный объект - объект, составленный из подобъектов. Подобъекты называются частями агрегата, и агрегат отвечает за них. Например, в системах с множественным наследованием шахматная фигура ферзь может быть унаследована от слона и ладьи. В системах с отсутствующим множественным наследованием можно получить ферзя двумя способами. Согласно первому способу, можно создать класс "любая_фигура" и далее, в периоде выполнения, делегировать полномочия каждому объекту-экземпляру данного класса быть ладьей, слоном, ферзей, пешкой и т. д. По второму способу после получения классов "ладья" и "слон" их можно объединить композицией в класс "ферзь". Теперь объект класса "ферзь" можно использовать как объект "ферзь" или даже как объект "слон", для чего объекту "ферзь" делегируется выполнение полномочий слона. Более того, можно делегировать объекту "ферзь" полномочия стать объектами "король" или даже "пешка"! Для композиции требуется, чтобы объединяемые объекты имели четко определенные интерфейсы. И у наследования, и у композиции есть достоинства и недостатки.

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

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

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

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

Это подводит еще к одному правилу объектно-ориентированного проектирования: предпочитайте композицию наследованию класса.

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

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

С помощью делегирования композицию можно сделать столь же мощным инструментом повторного использования, сколь и наследование. При делегировании в процесс обработки запроса вовлечено два объекта: получатель поручает выполнение операций другому объекту - уполномоченному. Примерно так же подкласс делегирует ответственность своему родительскому классу. Но унаследованная операция всегда может обратиться к объекту-получателю через переменную-член (в C++) или переменную self (в Smalltalk). Чтобы достичь того же эффекта для делегирования, получатель передает указатель на самого себя соответствующему объекту, чтобы при выполнении делегированной операции последний мог обратиться к непосредственному адресату запроса.

Например, вместо того чтобы делать класс Window (окно) подклассом класса Rectangle (прямоугольник) - ведь окно является прямоугольником, - мы можем воспользоваться внутри Window поведением класса Rectangle, поместив в класс Window переменную экземпляра типа Rectangle и делегируя ей операции, специфичные для прямоугольников. Другими словами, окно не является прямоугольником, а содержит его. Теперь класс Window может явно перенаправлять запросы своему члену Rectangle, а не наследовать его операции.

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

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

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

Характеристика 1. Любой предмет или явление могут рассматриваться как объект.

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

Характеристика 3. Объекты могут иметь открытые по интерфейсу методы обработки сообщений. Сами сообщения вызовов методов посылаются другими объектами, но для осуществления разумного интерфейса между объектами некоторые методы могут быть скрыты.

Характеристика 4. Вычисления осуществляются путем взаимодействия (обмена данными) между объектами, при котором один объект требует, чтобы другой объект выполнил некоторое действие (метод). Объекты взаимодействуют, посылая и получая сообщения. Сообщение - это запрос на выполнение действия, дополненный набором аргументов, которые могут понадобиться при выполнении действия. Объект - получатель сообщения - обрабатывает сообщения своими внутренними методами.

Характеристика 5. Каждый объект является представителем класса, который выражает общие свойства объектов данного класса в виде одинаковых списков набора данных (полей) в своей памяти и внутренних методов, обрабатывающих сообщения. В классе методы задают поведение объекта. Тем самым все объекты, которые являются экземплярами одного класса, могут выполнять одни и те же действия.

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

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

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

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

Из книги Самоучитель UML автора Леоненков Александр

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

Из книги Время - деньги. Создание команды разработчиков программного обеспечения автора Салливан Эд

Из книги Разгони свой сайт автора Мациевский Николай

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

Из книги Язык программирования С# 2005 и платформа.NET 2.0. автора Троелсен Эндрю

ГЛАВА 4. Язык C# 2.0 и объектно-ориентированный подход В предыдущей главе мы рассмотрели ряд базовых конструкций языка C# и платформы.NET, а также некоторые типы из пространства имен System. Здесь мы углубимся в детали процесса построения объектов. Сначала мы рассмотрим

автора Реймонд Эрик Стивен

Из книги Искусство программирования для Unix автора Реймонд Эрик Стивен

15.4.2. Утилита make в разработке не на C/C++ Программа make может оказаться полезной не только для программ на C/C++. Языки сценариев, подобные описанным в главе 14, могут не требовать традиционных этапов компиляции и компоновки, однако часто существуют другие виды зависимостей, с

Из книги Основы объектно-ориентированного программирования автора Мейер Бертран

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

Из книги Внедрение SAP R/3: Руководство для менеджеров и инженеров автора Кале Вивек

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

Из книги Программирование на языке Ruby [Идеология языка, теория и практика применения] автора Фултон Хэл

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

Из книги Интерактивные доски и их использование в учебном процессе автора Горюнова М. А.

Менеджмент, ориентированный на повышение эффективности Чтобы оправдать ожидания акционеров и повысить ценность компании, менеджеры компании должны не только уметь сформулировать стратегию, но и претворить ее в жизнь. Управление в стоимостном отношении (Value-based management, VBM)

Из книги Монетизация сайта. Секреты больших денег в Интернете автора Меркулов Андрей

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

Из книги C++ для начинающих автора Липпман Стенли

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

Из книги Все секреты Minecraft автора Миллер Меган

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

Из книги автора

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

Из книги автора

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

Из книги автора

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

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

Ладно. Введение это очень весело, но вы его все равно не читаете, так что кому интересно - добро пожаловать под кат!

Императивное программирование



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

Это были машинные коды, языки ассемблера и ранние высокоуровневые языки, вроде Fortran.

Ключевые моменты:

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

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

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

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

Основные понятия:

- Инструкция
- Состояние

Порожденные понятия:

- Присваивание
- Переход
- Память
- Указатель

Как основную:
- Языки ассемблера
- Fortran
- Algol
- Cobol
- Pascal
- C
- C++
- Ada
Как вспомогательную:
- Python
- Ruby
- Java
- C#
- PHP
- Haskell (через монады)

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

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



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

Основоположниками структурного программирования были такие знаменитые люди как Э. Дейкстра и Н. Вирт.

Языками-первопроходцами в этой парадигме были Fortran, Algol и B, позже их приемниками стали Pascal и C.

Ключевые моменты:

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

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

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

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

Основные понятия:

- Блок
- Цикл
- Ветвление

Языки поддерживающие данную парадигму:

Как основную:
- C
- Pascal
- Basic
Как вспомогательную:
- C#
- Java
- Python
- Ruby
- JavaScript

Поддерживают частично:
- Некоторые макроассемблеры (через макросы)

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

Процедурное программирование



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

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

Этим понятием на этот раз была процедура.

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

Ключевые моменты:

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

В современном программировании процедура может иметь несколько точек выхода (return в C-подобных языках), несколько точек входа (с помощью yield в Python или статических локальных переменных в C++), иметь аргументы, возвращать значение как результат своего выполнения, быть перегруженной по количеству или типу параметров и много чего еще.

Основные понятия:

- Процедура

Порожденные понятия:

- Вызов
- Аргументы
- Возврат
- Рекурсия
- Перегрузка

Языки поддерживающие данную парадигму:

Как основную:
- C
- C++
- Pascal
- Object Pascal
Как вспомогательную:
- C#
- Java
- Ruby
- Python
- JavaScript

Поддерживают частично:
- Ранний Basic

Стоит отметить, что несколько точек входа из всех этих языков поддерживаются только в Python.

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



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

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

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

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

Ключевые моменты:

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

Например файл List.mod включающий в себя класс List
и функции для работы с ним - модуль.

Папка Geometry, содержащая модули Shape, Rectangle и Triangle - тоже модуль, хоть и некоторые языки разделяют понятие модуля и пакета (в таких языках пакет - набор модулей и/или набор других пакетов).

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

Основные понятия:

- Модуль
- Импортирование

Порожденные понятия:

- Пакет
- Инкапсуляция

Языки поддерживающие данную парадигму:

Как основную:
- Haskell
- Pascal
- Python
Как вспомогательную:
- Java
- C#
- ActionScript 3

Поддерживают частично:
- C/C++

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

Вместо заключения

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

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

Соглашение об использовании материалов сайта

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

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

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

Подобные документы

    Вопросы программирования в Maple версий 6-11 и разработка приложений. Рассматривает эффективные приемы программирования и разработки приложений для многих разделов техники, математики, физики, для решения которых пакет не имеет стандартных средств.

    монография , добавлен 13.03.2008

    Объектно-ориентированный язык программирования: общая характеристика и свойства. Базовый и производный классы, конструкторы производного класса. Конструкторы и неопределенность при множественном наследовании. Роль наследования при разработке программ.

    курсовая работа , добавлен 23.12.2013

    Оформление технического задания на разработку программы или программного изделия для вычислительных машин и комплексов. Принципы объектно-ориентированного программирования в среде Delphi. Ознакомление на конкретных примерах с технологиями OLE и СОМ.

    отчет по практике , добавлен 04.02.2011

    Этапы создания программы. Транслятор как средство для преобразования текстов из одного языка в другой. Понятие языков программирования, основные моменты их истории. Некоторые операторы языка QBasic. Понятие переменной, ее наглядное представление.

    презентация , добавлен 16.06.2011

    Анализ принципа создания приложений для Linux. Состав стандартного проекта CLX, его иерархия классов, свойства, методы, отличия от VCL. Особенности кроссплатформенного программирования, а также дополнительные возможности кроссплатформенных приложений.

    курсовая работа , добавлен 25.12.2009

    C# как объектно-ориентированный язык программирования. Объектно-ориентированный анализ и проектирование системы на языке UML. Сущность программы "Учёт пациентов в регистратуре поликлиники", ее достоинства и недостатки, пошаговая инструкция пользователя.

    курсовая работа , добавлен 17.02.2013

    Исследование возможностей и областей использования языка программирования JavaScript. Сравнительный анализ языков программирования JavaScript и PHP. Разработка интерактивного Web-приложения на примере теста по теме "Программирование на языке Delphi".

    практическая работа , добавлен 04.02.2015

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

Клиентские языки

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

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

Самым распространенным из клиентских языков является Netscape совместно с компанией Sun Microsystems . Другой вариант клиентского языка это, например, VBScript .

Серверные языки

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

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

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


Wikimedia Foundation . 2010 .

Концепция объектно-ориентированного программирования (ООП) появилась более сорока лет назад, как развитие идей процедурного программирования. Идеология процедурного программирования, на мой взгляд, ничего особенного собой не представляет: все программы представлены набором процедур и функций, в то время как сами процедуры и функции – это последовательности операторов, выполняя которые модифицирует значения переменных в памяти. Основная программа в процедурном программировании также является процедурой (функцией), в теле которой могут быть вызовы других процедур и функций – подпрограмм. Суть процедурного программирования проста: данные отдельно, поведение отдельно. То (какие конструкции в него входят), я постарался собрать в отдельном разделе. Разделение кода на подпрограммы, во-первых, позволяет , а во-вторых, .

Идеология объектно-ориентированного программирования, как следует из самого названия, строится вокруг понятия объект. Объект объединяет в себе и данные и поведение. Объект – это любая сущность, с которой имеет дело программа, а именно: объекты предметной области, моделируемые программой; ресурсы операционной системы; сетевые протоколы и многое другое. По сути, объект – это та же , но дополненная процедурами и функциями, управляющими элементами этой структуры. К примеру, в процедурном языке программирования отдельно была бы создана переменная для хранения имени файла и отдельно – для хранения его дескриптора (уникальный идентификатор ресурса в операционной системе), а также ряд процедур работы с файлом: открыть файл, прочитать данные из файла и закрыть файл. Все бы эти процедуры, помимо обычных параметров и переменных для хранения результата, обязаны были бы принимать тот самый дескриптор, чтобы понять, о каком именно файле идет речь. В объектно-ориентированном языке для этих же целей был бы описан объект-файл, который также бы хранил внутри себя имя и дескриптор и предоставлял бы пользователю процедуры для открытия, чтения и закрытия себя самого (файла, ассоциированного с конкретным объектом). Разница была бы в том, что дескриптор был бы скрыт от остальной части программы, создавался бы в коде процедуры открытия файла и использовался бы неявно только самим объектом. Таким образом, пользователю объекта (программному коду внешней по отношению к объекту программы) не нужно было бы передавать дескриптор каждый раз в параметрах процедур. Объект – это комплект данных и методов работы с этими данными, часть из которых может быть скрыта от окружающего его мира, к которой и относятся детали реализации. Более подробно о терминологии объектно-ориентированного программирования будет рассказано далее.

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

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

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

Класс – тип данных, описывающий структуру и поведение объектов.

Объект – экземпляр класса.

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

Состояние объекта – набор текущих значений полей объекта.

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

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

Член класса – поля, методы и свойства класса.

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

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

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

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

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

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

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

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

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

    Наследование . Краеугольный камень ООП. В объектно-ориентированном программировании есть возможность наследовать структуру и поведение класса от другого класса. Класс, от которого наследуют, называется базовым или суперклассом, а класс, который получается вследствие наследования – производным или просто потомком. Любой класс может выступать как в роли суперкласса, так и в роли потомка. Связи наследования классов образуют иерархию классов. Множественным наследованием называют определение производного класса сразу от нескольких суперклассов. Не все объектно-ориентированные языки программирования поддерживают множественное наследование. Наследование – это эффективный способ выделения многократно используемых фрагментов кода, но у него есть и минусы, о которых будет рассказано далее.

    Абстрагирование . Возможность объединять классы в отдельные группы, выделяя общие, значимые для них всех характеристики (общие поля и общее поведение). Собственно, абстрагирование и есть следствие наследования: базовые классы не всегда имеют свою проекцию на объекты реального мира, а создаются исключительно с целью выделить общие черты целой группы объектов. К примеру, объект мебель – это базовое понятие для стола, стула и дивана, всех их объединяет то, что это движимое имущество, часть интерьера помещений, и они могут быть выполнены для дома или офиса, а также относиться к “эконом” или “премиум” классу. В ООП есть для этого отдельное понятие абстрактный класс – класс, объекты которого создавать запрещено, но можно использовать в качестве базового класса. Наследование и абстрагирование позволяют описывать структуры данных программы и связи между ними точно так же, как выглядят соответствующие им объекты в рассматриваемой .

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


    Диаграмма классов или иерархия наследования "Транспортные средства". Белые квадраты обозначают абстрактные классы.

    Полиморфизм . Еще одно свойство, которое является следствием наследования. Дело в том, что объектно-ориентированные языки программирования позволяют работать с набором объектов из одной иерархии точно так же, как если бы все они были объектами их базового класса. Если вернуться к примеру про мебель, то можно предположить, что в контексте создания информационной системы для мебельного магазина в базовый класс для всех видов мебели разумно добавить общий для всех метод “показать характеристики”. При распечатке характеристик всех видов товара программа бы без разбору для всех объектов вызывала бы этот метод, а каждый конкретный объект уже сам бы решал, какую информацию ему предоставлять. Как это реализуется: Во-первых, в базовом классе определяют общий для всех метод с общим для всех поведением. В случае с нашим примером это будет метод, печатающий общие для любых типов мебели параметры. Во-вторых, в каждом производном классе, где это необходимо, переопределяют базовый метод (добавляют метод с тем же именем), где расширяют базовое поведение своим, например, выводят характеристики, свойственные только конкретному виду мебельной продукции. Метод в базовом классе иногда вообще не обязан содержать какой-либо код, а необходим только для того, чтобы определить имя и набор параметров – сигнатуру метода. Такие методы называют абстрактными методами, а классы, их содержащие, автоматически становятся абстрактными классами. Итак, полиморфизм – это возможность единообразного общения с объектами разных классов через определенный интерфейс. Идеология полиморфизма гласит, что для общения с объектом вам не нужно знать его тип, а нужно знать, какой интерфейс он поддерживает.

    Интерфейс . В некоторых языках программирования (C#, Java) понятие интерфейса выделено явно - это не только открытые методы и свойства самого класса. Такие языки, как правило, не поддерживают множественного наследования и компенсируют это тем, что любой объект может иметь один базовый объект и реализовывать любое количество интерфейсов. Интерфейс в их интерпретации – это подобие абстрактного класса, содержащего только описание (сигнатуру) открытых методов и свойств. Реализация интерфейса ложится на плечи каждого класса, который собирается его поддерживать. Один и тот же интерфейс могут реализовывать классы абсолютно разных иерархий, что расширяет возможности полиморфизма. К примеру, интерфейс “сохранение/восстановление информации в базе данных” могли бы реализовывать как классы иерархии “мебель”, так и классы, связанные с оформлением заказов на изготовление мебели, а при нажатии на кнопку “сохранить” программа бы прошлась по всем объектами, запросила бы у них этот интерфейс и вызвала бы соответствующий метод.

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

Некоторые элементы современного объектно-ориентированного программирования

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

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

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

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

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

Про то, что популярность объектно-ориентированного подхода к огромна я уже сказал. Про то, что тех, кто стремится расширить эту парадигму довольно много, я тоже уже отметил. Но есть еще один способ выделиться среди огромного сообщества специалистов в информационных технологиях – это заявить, что ООП себя не оправдало, что это не панацея, а, скорее, плацебо. Есть среди этих людей действительно специалисты очень высокого класса, такие как , Александр Степанов, Эдсгер Дейкстра и другие, и их мнение заслуживает внимания, но есть и те, про которых говорят, что “плохому танцору всегда что-то мешает”. Вот они, наиболее очевидные недостатки ООП, на которые указывают специалисты:

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

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

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

Похожие публикации