stringtranslate.com

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

UML- нотация для класса. Этот класс Button имеет переменные для данных и функции . Посредством наследования можно создать подкласс как подмножество класса Button. Объекты являются экземплярами класса.

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

Многие из наиболее широко используемых языков программирования (таких как C++ , Java , [4] Python и т. д.) являются мультипарадигмальными и в большей или меньшей степени поддерживают объектно-ориентированное программирование, обычно в сочетании с императивным программированием , процедурным программированием. и функциональное программирование .

Важные объектно-ориентированные языки включают Ada , ActionScript , C++ , Common Lisp , C# , Dart , Eiffel , Fortran 2003 , Haxe , Java , [4] JavaScript , Kotlin , Logo , MATLAB , Objective-C , Object Pascal , Perl , PHP , Python , R , Raku , Ruby , Scala , SIMSCRIPT , Simula , Smalltalk , Swift , Vala и Visual Basic.NET .

История

Терминология, использующая «объекты» в современном понимании объектно-ориентированного программирования, впервые появилась в группе искусственного интеллекта Массачусетского технологического института в конце 1950-х — начале 1960-х годов. «Объект» относился к атомам LISP с идентифицированными свойствами (атрибутами). [5] [6] Еще одним ранним примером MIT был Sketchpad , созданный Иваном Сазерлендом в 1960–1961 годах; в глоссарии технического отчета 1963 года, основанного на его диссертации об Sketchpad, Сазерленд определил понятия «объект» и «экземпляр» (при этом концепция класса охватывается «главным» или «определением»), хотя и специализировалась на графическом взаимодействии. [7] Кроме того, в 1968 году версия MIT ALGOL , AED-0, установила прямую связь между структурами данных («плексами» на этом диалекте) и процедурами, предвосхищая то, что позже было названо «сообщениями», «методами» и «функции-члены». [8] [9] В то время часто обсуждались такие темы, как абстракция данных и модульное программирование .

Независимо от более поздних разработок MIT, таких как AED, Simula была разработана в 1961–1967 годах. [8] В Simula представлены важные концепции, которые сегодня являются неотъемлемой частью объектно-ориентированного программирования, такие как класс и объект , наследование и динамическое связывание . [10] Объектно-ориентированный язык программирования Simula использовался в основном исследователями, занимающимися физическим моделированием , например моделями для изучения и улучшения движения судов и их содержимого через грузовые порты. [10]

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

Алан Кей, [1]

Под влиянием работы в Массачусетском технологическом институте и языка Simula в ноябре 1966 года Алан Кей начал работать над идеями, которые в конечном итоге были включены в язык программирования Smalltalk . Кей использовал термин «объектно-ориентированное программирование» в разговоре еще в 1967 году. [1] Хотя его иногда называют «отцом объектно-ориентированного программирования», [11] Алан Кей отличил свое понятие ОО от более традиционных абстрактных данных . Типовое понятие объекта и подразумевал, что истеблишмент компьютерных наук не принял его понятие. [1] В записке MIT 1976 года, соавтором которой является Барбара Лисков, Simula 67 , CLU и Alphard перечислены как объектно-ориентированные языки, но не упоминается Smalltalk. [12]

В 1970-х годах первая версия языка программирования Smalltalk была разработана в Xerox PARC Аланом Кеем , Дэном Ингаллсом и Адель Голдберг . Smalltalk-72 включал в себя среду программирования, был динамически типизирован и сначала интерпретировался , а не компилировался . Smalltalk стал известен своим применением объектной ориентации на уровне языка и графической средой разработки. Smalltalk претерпел различные версии, и интерес к языку рос. [13] Хотя на Smalltalk повлияли идеи, представленные в Simula 67, он был спроектирован как полностью динамическая система, в которой классы можно было создавать и изменять динамически. [14]

В конце 1970-х и 1980-х годах объектно-ориентированное программирование приобрело известность. Объектно-ориентированный Lisp Flavors разрабатывался в 1979 году и включал в себя множественное наследование и примеси . [15] В 1981 году Голдберг редактировал августовский номер журнала Byte Magazine , знакомя широкую аудиторию с Smalltalk и объектно-ориентированным программированием. [16] LOOPS, объектная система для Interlisp -D, возникла под влиянием Smalltalk и Flavors, и статья о ней была опубликована в 1982 году. [17] В 1986 году Ассоциация вычислительной техники организовала первую конференцию по объектно-ориентированному программированию. , системы, языки и приложения (OOPSLA), в котором приняли участие 1000 человек. Среди других разработок была Common Lisp Object System , которая объединяет функциональное программирование и объектно-ориентированное программирование и допускает расширение через метаобъектный протокол . В 1980-х годах было предпринято несколько попыток разработать архитектуру процессора, включающую аппаратную поддержку объектов в памяти, но они не увенчались успехом. Примеры включают Intel iAPX 432 и Linn Smart Rekursiv .

В середине 1980-х годов Objective-C был разработан Брэдом Коксом , который использовал Smalltalk в ITT Inc. Бьерн Страуструп , который использовал Simula для своей докторской диссертации, создал объектно-ориентированный C++ . [13] В 1985 году Бертран Мейер также создал первый дизайн Эйфелевого языка . Ориентированный на качество программного обеспечения, Eiffel представляет собой чисто объектно-ориентированный язык программирования и систему обозначений, поддерживающую весь жизненный цикл программного обеспечения. Мейер описал метод разработки программного обеспечения Эйфеля, основанный на небольшом количестве ключевых идей из области разработки программного обеспечения и информатики, в книге « Объектно-ориентированное создание программного обеспечения ». Важным для обеспечения качества Eiffel является механизм надежности Мейера « Проектирование по контракту» , который является неотъемлемой частью как метода, так и языка.

В начале и середине 1990-х годов объектно-ориентированное программирование стало доминирующей парадигмой программирования , когда языки программирования, поддерживающие эти методы, стали широко доступны. В их число входили Visual FoxPro 3.0, [18] [ 19] [20] C++ , [ 21 ] и Delphi . Его доминирование еще больше усилилось за счет растущей популярности графических пользовательских интерфейсов , которые в значительной степени опираются на методы объектно-ориентированного программирования. Пример тесно связанной библиотеки динамического графического интерфейса и языка ООП можно найти в фреймворках Cocoa в Mac OS X , написанных на Objective-C , объектно-ориентированном расширении динамического обмена сообщениями для C на основе Smalltalk. Наборы инструментов ООП также повысили популярность событийно-ориентированного программирования (хотя эта концепция не ограничивается ООП).

В ETH Zürich Никлаус Вирт и его коллеги исследовали концепцию проверки типов за пределами модулей. Modula-2 (1978) включала эту концепцию, а их последующий проект Oberon включал особый подход к объектной ориентации, классам и тому подобному. Наследование не является очевидным в конструкции Вирта, поскольку его номенклатура смотрит в противоположном направлении: это называется расширением типа, и точка зрения ведется от родителя вниз к наследнику.

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

Совсем недавно появились некоторые языки, которые в основном объектно-ориентированы, но также совместимы с процедурной методологией. Два таких языка — Python и Ruby . Вероятно, наиболее коммерчески важными объектно-ориентированными языками последнего времени являются Java , разработанный Sun Microsystems , а также C# и Visual Basic.NET (VB.NET), оба разработаны для платформы Microsoft .NET . Каждая из этих двух структур по-своему демонстрирует преимущества использования ООП за счет создания абстракции от реализации. VB.NET и C# поддерживают межъязыковое наследование, позволяя классам, определенным на одном языке, создавать подклассы классов, определенных на другом языке.

Функции

Объектно-ориентированное программирование использует объекты, но не все связанные с ним методы и структуры поддерживаются непосредственно в языках, которые утверждают, что поддерживают ООП. Перечисленные ниже функции являются общими для языков, которые считаются строго классовыми и объектно-ориентированными (или мультипарадигмальными с поддержкой ООП), с упомянутыми примечательными исключениями. [22] [23] [24] [25] Кристофер Дж. Дейт заявил, что критическое сравнение ООП с другими технологиями, в частности с реляционными, затруднено из-за отсутствия согласованного и строгого определения ООП. [26]

Совместно с языками, не поддерживающими ООП.

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

Объекты

Объекты иногда соответствуют вещам, найденным в реальном мире. Например, графическая программа может иметь такие объекты, как «круг», «квадрат» и «меню». Система онлайн-покупок может иметь такие объекты, как «корзина», «клиент» и «продукт». [27] Иногда объекты представляют собой более абстрактные сущности, например, объект, представляющий открытый файл, или объект, предоставляющий услугу перевода измерений из обычного США в метрические системы. Доступ к объектам похож на переменные со сложной внутренней структурой, и во многих языках они фактически являются указателями , служащими фактическими ссылками на один экземпляр указанного объекта в памяти в куче или стеке. Процедуры известны как методы ; переменные также известны как поля , члены, атрибуты или свойства.

Объекты могут содержать другие объекты в своих переменных экземпляра; это известно как композиция объекта . Например, объект класса «Сотрудник» может содержать (напрямую или через указатель) объект класса «Адрес» в дополнение к своим собственным переменным экземпляра, таким как «first_name» и «position». Композиция объектов используется для представления отношений «имеет»: у каждого сотрудника есть адрес, поэтому каждый объект «Сотрудник» имеет доступ к месту для хранения объекта «Адрес» (либо непосредственно встроенного в него самого, либо в отдельном месте, адресуемом через указатель). Дэйт и Дарвен предложили теоретическую основу, которая использует ООП как своего рода настраиваемую систему типов для поддержки РСУБД , но запрещает указатели на объекты. [28]

Парадигму ООП критиковали за чрезмерный акцент на использовании объектов для проектирования и моделирования программного обеспечения в ущерб другим важным аспектам (вычислениям/алгоритмам). [29] [30] Например, Роб Пайк сказал, что ООП-языки часто смещают фокус со структур данных и алгоритмов на типы . [31] Стив Йегге заметил, что в отличие от функционального программирования : [32]

Объектно-ориентированное программирование ставит существительные на первое место. Зачем вам идти на все, чтобы поставить одну часть речи на пьедестал? Почему одна концепция должна иметь приоритет над другой? Это не значит, что ООП внезапно сделал глаголы менее важными в нашем способе мышления. Это странно искаженная перспектива.

Рич Хики , создатель Clojure , описывал объектные системы как чрезмерно упрощенные модели реального мира. Он подчеркнул неспособность ООП правильно моделировать время, что становится все более проблематичным по мере того, как программные системы становятся все более параллельными. [30]

Александр Степанов невыгодно сравнивает объектную ориентацию с обобщенным программированием : [29]

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

Наследование

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

В программировании на основе классов , самом популярном стиле, каждый объект должен быть экземпляром определенного класса . Класс определяет формат или тип данных (включая переменные-члены и их типы) и доступные процедуры (методы класса или функции-члены) для данного типа или класса объекта. Объекты создаются путем вызова специального типа метода в классе, известного как конструктор . Классы могут наследовать от других классов, поэтому они располагаются в иерархии, представляющей отношения «является типом». Например, класс «Сотрудник» может наследовать от класса «Человек». Все данные и методы, доступные родительскому классу, также появляются в дочернем классе с теми же именами. Например, класс Person может определить переменные «first_name» и «last_name» с помощью метода make_full_name(). Они также будут доступны в классе «Сотрудник», который может добавить переменные «должность» и «зарплата». Гарантируется, что все экземпляры класса «Сотрудник» будут иметь одинаковые атрибуты, такие как имя, должность и зарплата. Процедуры и переменные могут быть специфичными либо для класса, либо для экземпляра; это приводит к следующим условиям:

В зависимости от определения языка подклассы могут иметь или не иметь возможность переопределять методы, определенные суперклассами. В некоторых языках разрешено множественное наследование , хотя это может затруднить разрешение переопределений. В некоторых языках есть специальная поддержка других концепций, таких как черты и примеси , однако в любом языке с множественным наследованием примесь — это просто класс, который не представляет отношения типа «является типом». Миксины обычно используются для добавления одних и тех же методов к нескольким классам. Например, класс UnicodeConversionMixin может предоставлять метод unicode_to_ascii(), если он включен в класс FileReader и класс WebPageScraper, которые не имеют общего родительского элемента.

Абстрактные классы не могут быть преобразованы в объекты; они существуют только для наследования в другие «конкретные» классы, экземпляры которых могут быть созданы. В Java finalключевое слово можно использовать для предотвращения создания подклассов класса. [33]

Напротив, в программировании на основе прототипов объекты являются основными сущностями. Вообще понятия «класс» даже не существует. Скорее, прототип или родительский объект — это просто другой объект, с которым этот объект связан. В Self объект может иметь несколько родителей или не иметь их, [34] но в самом популярном языке, основанном на прототипах, Javascript, каждый объект имеет одну ссылку на прототип (и только одну). Новые объекты могут создаваться на основе уже существующих объектов, выбранных в качестве их прототипа. Вы можете назвать два разных объекта — яблоко и апельсин — фруктом, если объект- фрукт существует и прототипом для яблока и апельсина является фрукт . Идея класса фруктов не существует в явном виде, но может быть смоделирована как класс эквивалентности объектов, имеющих один и тот же прототип, или как набор объектов, удовлетворяющих определенному интерфейсу ( утиная типизация ). В отличие от программирования на основе классов, в языках, основанных на прототипах, обычно можно определять атрибуты и методы, не используемые совместно с другими объектами; например, атрибут Sugar_content может быть определен в Apple , но не в Orange .

Доктрина композиции вместо наследования выступает за реализацию отношений has-a с использованием композиции вместо наследования. Например, вместо того, чтобы наследовать от класса Person, класс «Сотрудник» может предоставить каждому объекту «Сотрудник» внутренний объект «Человек», который затем будет иметь возможность скрыть от внешнего кода, даже если класс «Сотрудник» имеет много общедоступных атрибутов или методов. Некоторые языки, такие как Go, вообще не поддерживают наследование. Go заявляет, что он объектно-ориентирован, [35] а Бьёрн Страуструп, автор C++, заявил, что ООП можно использовать без наследования. [36] Делегирование — еще одна особенность языка, которую можно использовать в качестве альтернативы наследованию. Роб Пайк назвал объектно-ориентированное программирование « римскими цифрами вычислений» [37] и приводит пример профессора Java , чьим «идиоматическим» решением проблемы было создание шести новых классов, а не просто использование таблицы поиска . [38]

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

Динамическая отправка/передача сообщений

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

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

Абстракция и инкапсуляция данных

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

В объектно-ориентированном программировании объекты предоставляют уровень, который можно использовать для отделения внутреннего кода от внешнего и реализации абстракции и инкапсуляции. Внешний код может использовать объект только путем вызова определенного метода экземпляра с определенным набором входных параметров, чтения переменной экземпляра или записи в переменную экземпляра. Во время работы программа может создавать множество экземпляров объектов, которые работают независимо. Утверждается, что этот метод позволяет легко повторно использовать одни и те же процедуры и определения данных для разных наборов данных, а также потенциально интуитивно отражает отношения реального мира. Вместо использования таблиц базы данных и программных процедур разработчик использует объекты, с которыми пользователь может быть более знаком: объекты из своей области приложения. [40] Утверждения о том, что парадигма ООП повышает возможность повторного использования и модульность, подверглись критике. [41] [42]

Если класс не позволяет вызывающему коду получать доступ к внутренним данным объекта и разрешает доступ только через методы, это также является формой сокрытия информации. Некоторые языки (например, Java) позволяют классам явно применять ограничения доступа, например, обозначая внутренние данные ключевым словом privateи обозначая методы, предназначенные для использования кодом вне класса, с помощью этого publicключевого слова. [43] Методы также могут быть разработаны на общедоступном, частном или промежуточном уровнях, например protected(что обеспечивает доступ из того же класса и его подклассов, но не к объектам другого класса). [43] В других языках (например, Python) это применяется только по соглашению (например, privateимена методов могут начинаться с подчеркивания ). В языках C#, Swift и Kotlin internalключевое слово разрешает доступ только к файлам, присутствующим в той же сборке, пакете или модуле, что и класс. [44]

В языках программирования, особенно в объектно-ориентированных, жизненно важен акцент на абстракции. Объектно-ориентированные языки расширяют понятие типа, включив в него абстракцию данных, подчеркивая важность ограничения доступа к внутренним данным с помощью методов. [45] Эрик С. Рэймонд написал, что объектно-ориентированные языки программирования имеют тенденцию поощрять многоуровневые программы, которые разрушают прозрачность. [46] Рэймонд сравнивает это с подходом, использованным в Unix и языке программирования C, в неблагоприятную сторону . [46]

« Принцип открытости/закрытости » утверждает, что классы и функции «должны быть открыты для расширения, но закрыты для модификации». Лука Карделли утверждал, что ООП-языки обладают «чрезвычайно плохими свойствами модульности в отношении расширения и модификации классов» и, как правило, чрезвычайно сложны. [41] Последний момент повторяет Джо Армстронг , главный изобретатель Эрланга , который цитирует слова: [42]

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

Лео Броди предположил связь между автономной природой объектов и тенденцией к дублированию кода [47] в нарушение принципа «не повторяйся» [48] разработки программного обеспечения.

Полиморфизм

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

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

Это еще один тип абстракции, который упрощает код, внешний по отношению к иерархии классов, и обеспечивает четкое разделение задач .

Открытая рекурсия

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

ООП-языки

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

Популярность и прием

График индекса популярности языка программирования TIOBE с 2002 по 2023 год. В 2000-х годах за первое место боролись объектно-ориентированный Java (оранжевый) и процедурный C (темно-синий).

Многие широко используемые языки, такие как C++, Java и Python, предоставляют объектно-ориентированные функции. Хотя в прошлом объектно-ориентированное программирование было широко распространено, в последнее время [50] эссе, критикующие объектно-ориентированное программирование и рекомендующие избегать этих функций (как правило, в пользу функционального программирования ), стали очень популярны в сообществе разработчиков. [51] Пол Грэм предположил, что популярность ООП в крупных компаниях обусловлена ​​«большими (и часто меняющимися) группами посредственных программистов». По словам Грэма, дисциплина, налагаемая ООП, не позволяет одному программисту «нанести слишком большой ущерб». [52] Эрик С. Рэймонд , программист Unix и сторонник программного обеспечения с открытым исходным кодом , критически относился к заявлениям, которые представляют объектно-ориентированное программирование как «единственное истинное решение». [46]

Ричард Фельдман утверждает, что эти языки, возможно, улучшили свою модульность за счет добавления объектно-ориентированных функций, но они стали популярными по причинам, не связанным с объектно-ориентированностью. [53] В статье Лоуренс Крубнер утверждал, что по сравнению с другими языками (диалектами LISP, функциональными языками и т. д.) ООП-языки не обладают уникальными преимуществами и накладывают тяжелое бремя ненужной сложности. [54] Исследование Potok et al. не показал существенной разницы в производительности между ООП и процедурными подходами. [55] Лука Карделли заявил, что ООП-код «по сути менее эффективен», чем процедурный код, и что компиляция ООП может занять больше времени. [41]

ООП в динамических языках

В последние годы объектно-ориентированное программирование стало особенно популярным в языках динамического программирования . Python , PowerShell , Ruby и Groovy — динамические языки, построенные на принципах ООП, тогда как в Perl и PHP добавляются объектно-ориентированные функции начиная с Perl 5 и PHP 4, а в ColdFusion — с версии 6.

Объектная модель документов HTML , XHTML и XML в Интернете имеет привязки к популярному языку JavaScript / ECMAScript . JavaScript, пожалуй, самый известный язык программирования на основе прототипов , который использует клонирование прототипов, а не наследование от класса (в отличие от программирования на основе классов ). Другой язык сценариев, использующий этот подход, — Lua .

ООП в сетевом протоколе

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

Первоначальная версия DDM определяла распределенные файловые службы. Позже она была расширена и стала основой архитектуры распределенной реляционной базы данных (DRDA).

Шаблоны проектирования

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

Наследование и поведенческие подтипы

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

Шаблоны проектирования «Банда четырех»

«Шаблоны проектирования: элементы объектно-ориентированного программного обеспечения многократного использования» — влиятельная книга, опубликованная в 1994 году Эрихом Гаммой , Ричардом Хелмом , Ральфом Джонсоном и Джоном Влиссайдсом , которую часто с юмором называют «Бандой четырех». Наряду с изучением возможностей и подводных камней объектно-ориентированного программирования, в нем описываются 23 распространенные проблемы программирования и шаблоны для их решения.

В книге описаны следующие закономерности:

Объектная ориентация и базы данных

И объектно-ориентированное программирование, и системы управления реляционными базами данных (СУБД) сегодня чрезвычайно распространены в программном обеспечении . Поскольку реляционные базы данных не хранят объекты напрямую (хотя некоторые СУБД имеют объектно-ориентированные функции, позволяющие приблизиться к этому), существует общая потребность соединить два мира. Проблема объединения доступа к объектно-ориентированному программированию и шаблонов данных с реляционными базами данных известна как объектно-реляционное несоответствие импеданса . Есть несколько подходов к решению этой проблемы, но общего решения без недостатков не существует. [56] Одним из наиболее распространенных подходов является объектно-реляционное отображение , которое встречается в языках IDE , таких как Visual FoxPro , и таких библиотеках, как Java Data Objects и Ruby on Rails ActiveRecord.

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

Реальное моделирование и отношения

ООП можно использовать для связывания объектов и процессов реального мира с цифровыми аналогами. Однако не все согласны с тем, что ООП облегчает прямое картографирование реального мира (см. раздел «Критика») или что картографирование реального мира является даже достойной целью; Бертран Мейер в «Объектно-ориентированном построении программного обеспечения» [57] утверждает , что программа — это не модель мира, а модель некоторой части мира; «Реальность — дважды удаленная кузина». В то же время отмечены некоторые принципиальные ограничения ООП. [58] Например, проблему круг-эллипс трудно решить, используя концепцию наследования ООП .

Однако Никлаус Вирт (который популяризировал поговорку, теперь известную как закон Вирта : «Программное обеспечение становится медленнее быстрее, чем аппаратное обеспечение становится быстрее») в своей статье «Хорошие идеи в Зазеркалье» сказал об ООП: «Эта парадигма близко отражает структуру систем «в реальном мире», и поэтому он хорошо подходит для моделирования сложных систем со сложным поведением» [59] ( принцип контраста KISS ).

Стив Йегге и другие отметили, что в естественных языках отсутствует ООП-подход, при котором строго расставляется приоритет вещей (объектов/ существительных ) перед действиями (методами/ глаголами ). [60] Эта проблема может привести к тому, что ООП будет иметь более запутанные решения, чем процедурное программирование. [61]

ООП и поток управления

ООП было разработано для повышения возможности повторного использования и удобства сопровождения исходного кода. [62] Прозрачное представление потока управления не имело приоритета и должно было обрабатываться компилятором. С ростом актуальности параллельного оборудования и многопоточного кодирования разработка прозрачного потока управления становится все более важной, чего трудно достичь с помощью ООП. [63] [64] [65] [66]

Ответственность и дизайн, управляемый данными

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

Рекомендации SOLID и GRASP

SOLID — это мнемоника, изобретенная Майклом Физерсом, которая описывает пять принципов проектирования программного обеспечения:

GRASP (Общие шаблоны программного обеспечения для распределения ответственности) — это еще один набор руководящих принципов, предложенных Крейгом Ларманом .

Формальная семантика

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

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

Попытки найти согласованное определение или теорию, лежащую в основе объектов, оказались не очень успешными (однако формальные определения многих концепций и конструкций ООП см. в книге Абади и Карделли, «Теория объектов » [68] ) и часто сильно расходятся. Например, некоторые определения сосредоточены на умственной деятельности, а некоторые — на структурировании программ. Одно из более простых определений заключается в том, что ООП — это использование структур данных или массивов «карты», которые могут содержать функции и указатели на другие карты, и все это с некоторым синтаксическим сахаром и областью видимости сверху. Наследование может осуществляться путем клонирования карт (иногда это называется «прототипированием»).

Смотрите также

Системы

Языки моделирования

Рекомендации

  1. ^ abcd «Доктор Алан Кей о значении «объектно-ориентированного программирования»» . 2003 . Проверено 11 февраля 2010 г.
  2. ^ Киндлер, Э.; Кривой, И. (2011). «Объектно-ориентированное моделирование систем со сложным управлением». Международный журнал общих систем: 313–343. {{cite journal}}: Требуется цитировать журнал |journal=( помощь )
  3. ^ Льюис, Джон; Лофтус, Уильям (2008). Программные решения на Java. Основы проектирования программирования. 6-е изд . ISBN Pearson Education Inc. 978-0-321-53205-3., раздел 1.6 «Объектно-ориентированное программирование»
  4. ^ ab Bloch 2018, стр. xi–xii, Предисловие.
  5. ^ Маккарти, Дж.; Брайтон, Р.; Эдвардс, Д.; Фокс, П .; Ходс, Л. ; Лакхэм, Д .; Малинг, К.; Парк, Д. ; Рассел, С. (март 1969 г.). «Руководство программиста LISP I» (PDF) . Вычислительный центр и научно-исследовательская лаборатория электроники . Бостон , Массачусетс : Группа искусственного интеллекта, Вычислительный центр и исследовательская лаборатория Массачусетского технологического института: 88f. Архивировано из оригинала (PDF) 17 июля 2010 года . На местном жаргоне MIT списки ассоциаций [атомарных символов] также называются «списками свойств», а атомарные символы иногда называются «объектами».
  6. ^ Маккарти, Джон ; Абрахамс, Пол В.; Эдвардс, Дэниел Дж.; Харт, свапнил д.; Левин, Майкл И. (1962). Руководство программиста LISP 1.5. МТИ Пресс . п. 105. ИСБН 978-0-262-13011-0. Объект — синоним атомарного символа
  7. ^ Сазерленд, IE (30 января 1963 г.). «Альбом для рисования: человеко-машинная графическая система связи». Технический отчет № 296, Лаборатория Линкольна, Массачусетский технологический институт через Центр технической информации Министерства обороны (stinet.dtic.mil). Архивировано из оригинала 8 апреля 2013 года . Проверено 17 июля 2019 г.
  8. ^ ab The Development of the Simula Languages, Кристен Найгаард , Оле-Йохан Даль , стр.254 Uni-kl.ac.at. Архивировано 28 августа 2006 г. на Wayback Machine.
  9. ^ Росс, Дуг. «Первый язык разработки программного обеспечения». График работы лаборатории LCS/AI . Лаборатория компьютерных наук и искусственного интеллекта Массачусетского технологического института . Проверено 13 мая 2010 г.
  10. ^ Аб Холмевик, Ян Руне (1994). «Компиляция Simula: историческое исследование генезиса технологий» (PDF) . IEEE Анналы истории вычислений . 16 (4): 25–37. дои : 10.1109/85.329756. S2CID  18148999. Архивировано из оригинала (PDF) 30 августа 2017 года . Проверено 3 марта 2018 г.
  11. Мясник, Пол (30 июня 2014 г.). Семь моделей параллелизма за семь недель: когда потоки распадаются. Прагматичная книжная полка. п. 204. ИСБН 978-1-68050-466-8.
  12. ^ Джонс, Анита К.; Лисков, Барбара Х. (апрель 1976 г.). Средство контроля доступа для языков программирования (PDF) (технический отчет). Массачусетский технологический институт. Памятка CSG 137.
  13. ^ аб Бертран Мейер (2009). Прикосновение к классу: учимся хорошо программировать с объектами и контрактами . Springer Science & Business Media. п. 329. Бибкод : 2009tclp.book.....М. ISBN 978-3-540-92144-8.
  14. ^ Кей, Алан. «Ранняя история Smalltalk». Архивировано из оригинала 10 июля 2008 года . Проверено 13 сентября 2007 г.
  15. ^ Мун, Дэвид А. (июнь 1986 г.). «Объектно-ориентированное программирование с разными вкусами» (PDF) . Материалы конференции «Языки и приложения объектно-ориентированных систем программирования ». УПСЛА '86. стр. 1–8. дои : 10.1145/28697.28698. ISBN 978-0-89791-204-4. S2CID  17150741 . Проверено 17 марта 2022 г.
  16. ^ «Представляем зоопарк Smalltalk». ЧМ . 17 декабря 2020 г.
  17. ^ Бобров, Д.Г.; Стефик, MJ (1982). LOOPS: данные и объектно-ориентированное программирование для Interlisp (PDF) . Европейская конференция по искусственному интеллекту.
  18. ^ 1995 (июнь) Visual FoxPro 3.0, FoxPro развивается из процедурного языка в объектно-ориентированный язык. Visual FoxPro 3.0 представляет контейнер базы данных, универсальные возможности клиент/сервер, поддержку технологий ActiveX, а также OLE-автоматизацию и поддержку нулевых значений. Краткое изложение релизов Fox
  19. ^ Веб-сайт истории FoxPro: Foxprohistory.org
  20. ^ Руководство рецензента 1995 г. по Visual FoxPro 3.0: DFpug.de
  21. Хурана, Рохит (1 ноября 2009 г.). Объектно-ориентированное программирование на C++, 1E. Издательский дом Викас Пвт Лимитед. ISBN 978-81-259-2532-3.
  22. ^ Дебора Дж. Армстронг. Кварки объектно-ориентированной разработки . Обзор компьютерной литературы за почти 40 лет выявил несколько фундаментальных понятий, встречающихся в подавляющем большинстве определений ООП, в порядке убывания популярности: наследование, объект, класс, инкапсуляция, метод, передача сообщений, полиморфизм и абстракция.
  23. ^ Джон К. Митчелл , Концепции языков программирования , Cambridge University Press, 2003, ISBN 0-521-78098-5 , стр.278. Списки: динамическая диспетчеризация, абстракция, полиморфизм подтипов и наследование. 
  24. ^ Майкл Ли Скотт, Прагматика языка программирования , издание 2, Morgan Kaufmann, 2006, ISBN 0-12-633951-1 , стр. 470. Перечисляет инкапсуляцию, наследование и динамическую отправку. 
  25. ^ Пирс, Бенджамин (2002). Типы и языки программирования . МТИ Пресс. ISBN 978-0-262-16209-8., раздел 18.1 «Что такое объектно-ориентированное программирование?» Списки: динамическая диспетчеризация, инкапсуляция или несколько методов (множественная диспетчеризация), полиморфизм подтипов, наследование или делегирование, открытая рекурсия («это»/«сам»)
  26. ^ CJ Date, Введение в системы баз данных, 6-е изд., Стр. 650
  27. ^ Буч, Грейди (1986). Разработка программного обеспечения с использованием Ada. Эддисон Уэсли. п. 220. ИСБН 978-0-8053-0608-8. Возможно, самая сильная сторона объектно-ориентированного подхода к разработке заключается в том, что он предлагает механизм, отражающий модель реального мира.
  28. ^ CJ Date, Хью Дарвен. Фонд будущих систем баз данных: Третий манифест (2-е издание)
  29. ^ аб Степанов, Александр . «СТЛпорт: Интервью с А. Степановым» . Проверено 21 апреля 2010 г.
  30. ^ ab Рич Хики, основной доклад на саммите JVM Languages ​​Summit 2009, «Мы уже там?» Ноябрь 2009 года.
  31. Пайк, Роб (25 июня 2012 г.). «Меньше значит экспоненциально больше» . Проверено 1 октября 2016 г.
  32. ^ "Блог Стиви Разглагольствования: Казнь в Королевстве существительных" . Проверено 20 мая 2020 г.
  33. ^ Блох 2018, с. 19, Глава §2, пункт 4. Обеспечьте отсутствие возможности создания экземпляров с помощью частного конструктора.
  34. ^ Дони, С; Маленфант, Дж; Бардон, Д. (1999). «Классификация языков программирования, основанных на прототипах» (PDF) . Программирование на основе прототипов: концепции, языки и приложения . Сингапур Берлин Гейдельберг: Springer. ISBN 9789814021258.
  35. ^ "Является ли Go объектно-ориентированным языком?" . Проверено 13 апреля 2019 г. Хотя Go имеет типы и методы и допускает объектно-ориентированный стиль программирования, иерархии типов здесь нет.
  36. ^ Страуструп, Бьярн (2015). Объектно-ориентированное программирование без наследования (приглашенный доклад). 29-я Европейская конференция по объектно-ориентированному программированию (ECOOP 2015). 1:34. doi :10.4230/LIPIcs.ECOOP.2015.1.
  37. Пайк, Роб (2 марта 2004 г.). «[9fans] Re: Threads: Пришивание почетных знаков на ядро». comp.os.plan9 (список рассылки) . Проверено 17 ноября 2016 г. .
  38. Пайк, Роб (14 ноября 2012 г.). «Несколько лет назад я увидел эту страницу». Архивировано из оригинала 14 августа 2018 года . Проверено 1 октября 2016 г.
  39. ^ "Принципы дяди Боба SOLID" . YouTube .
  40. ^ Якобсен, Ивар; Магнус Кристерсон; Патрик Йонссон; Гуннар Овергаард (1992). Объектно-ориентированная разработка программного обеспечения. Аддисон-Уэсли ACM Press. стр. 43–69. ISBN 978-0-201-54435-0.
  41. ^ abc Карделли, Лука (1996). «Плохие инженерные свойства объектно-ориентированных языков». АКМ Компьютер. Сурв . 28 (4с): 150–с. дои : 10.1145/242224.242415. ISSN  0360-0300. S2CID  12105785 . Проверено 21 апреля 2010 г.
  42. ^ аб Армстронг, Джо. В книге «Кодеры за работой: размышления о ремесле программирования». Питер Сейбел, изд. Codersatwork.com. Архивировано 5 марта 2010 г. на Wayback Machine , по состоянию на 13 ноября 2009 г.
  43. ^ ab Bloch 2018, стр. 73–77, глава §4, пункт 15. Минимизируйте доступность классов и членов.
  44. ^ «Что такое объектно-ориентированное программирование (ООП) простыми словами? - Software Geek Bytes» . 5 января 2023 г. Проверено 17 января 2023 г.
  45. ^ Карделли, Лука; Вегнер, Питер (10 декабря 1985 г.). «О понимании типов, абстракции данных и полиморфизме». Обзоры вычислительной техники ACM . 17 (4): 471–523. дои : 10.1145/6041.6042 . ISSN  0360-0300.
  46. ^ abc Эрик С. Рэймонд (2003). «Искусство программирования для Unix: Unix и объектно-ориентированные языки» . Проверено 6 августа 2014 г.
  47. ^ Броди, Лео (1984). Думая дальше (PDF) . стр. 92–93 . Проверено 4 мая 2018 г.
  48. ^ Хант, Эндрю. «Не повторяйся». Категория Экстремальное программирование . Проверено 4 мая 2018 г.
  49. ^ «Изумрудный язык программирования». 26 февраля 2011 г.
  50. ^ Брукер, Ахим Д.; Вольф, Буркхарт (2008). «Расширяемые вселенные для объектно-ориентированных моделей данных». ЭКООП 2008 – Объектно-ориентированное программирование . Конспекты лекций по информатике. Том. 5142. стр. 438–462. дои : 10.1007/978-3-540-70592-5_19. ISBN 978-3-540-70591-8. объектно-ориентированное программирование — широко распространенная парадигма программирования.
  51. Кассель, Дэвид (21 августа 2019 г.). «Почему так много разработчиков ненавидят объектно-ориентированное программирование?». Новый стек .
  52. ^ Грэм, Пол . «Почему ARC не особенно объектно-ориентирован». ПолГрэм.com . Проверено 13 ноября 2009 г.
  53. ^ Фельдман, Ричард. «Почему функциональное программирование не является нормой?». YouTube .
  54. ^ Крубнер, Лоуренс. «Объектно-ориентированное программирование — это дорогостоящая катастрофа, которой необходимо положить конец». smashcompany.com. Архивировано из оригинала 14 октября 2014 года . Проверено 14 октября 2014 г.
  55. ^ Поток, Томас; Младен Воук; Энди Риндос (1999). «Анализ производительности объектно-ориентированного программного обеспечения, разработанного в коммерческой среде» (PDF) . Программное обеспечение: практика и опыт . 29 (10): 833–847. doi :10.1002/(SICI)1097-024X(199908)29:10<833::AID-SPE258>3.0.CO;2-P. S2CID  57865731 . Проверено 21 апреля 2010 г.
  56. Ньюард, Тед (26 июня 2006 г.). «Вьетнам компьютерных наук». Взаимодействие происходит. Архивировано из оригинала 4 июля 2006 года . Проверено 2 июня 2010 г.
  57. ^ Мейер, второе издание, с. 230
  58. ^ М.Трофимов, ОООП - Третье решение «О»: открытое ООП. Первый класс, OMG , 1993, Vol. 3, вып. 3, стр.14.
  59. ^ Вирт, Никлаус (2006). «Хорошие идеи в Зазеркалье» (PDF) . Компьютер . 39 (1): 28–39. дои : 10.1109/mc.2006.20. S2CID  6582369. Архивировано из оригинала (PDF) 12 октября 2016 года . Проверено 2 октября 2016 г.
  60. ^ Йегге, Стив (30 марта 2006 г.). «Казнь в царстве существительных». steve-yegge.blogspot.com . Проверено 3 июля 2010 г.
  61. Борончик, Тимоти (11 июня 2009 г.). «Что не так с ООП». zaemis.blogspot.com . Проверено 3 июля 2010 г.
  62. Эмблер, Скотт (1 января 1998 г.). «Реалистичный взгляд на объектно-ориентированное повторное использование». drdobbs.com . Проверено 4 июля 2010 г.
  63. Шелли, Асаф (22 августа 2008 г.). «Недостатки объектно-ориентированного моделирования». Сеть программного обеспечения Intel . Проверено 4 июля 2010 г.
  64. Джеймс, Джастин (1 октября 2007 г.). «Многопоточность — это глагол, а не существительное». techrepublic.com. Архивировано из оригинала 10 октября 2007 года . Проверено 4 июля 2010 г.
  65. Шелли, Асаф (22 августа 2008 г.). «КАК: Многоядерное программирование (многопроцессорная обработка) Рекомендации по проектированию классов Visual C++, функции-члены». support.microsoft.com . Проверено 4 июля 2010 г.
  66. Роберт Харпер (17 апреля 2011 г.). «Некоторые мысли об обучении ФП». Блог экзистенциального типа . Проверено 5 декабря 2011 г.
  67. ^ Опрос, Эрик. «Подтипирование и наследование категориальных типов данных» (PDF) . Проверено 5 июня 2011 г.
  68. ^ Аб Абади, Мартин ; Карделли, Лука (1996). Теория объектов. Springer-Verlag New York, Inc. ISBN 978-0-387-94775-4. Проверено 21 апреля 2010 г.

дальнейшее чтение

Внешние ссылки