The following text is a partial translation of the original English article, performed by ChatGPT (gpt-3.5-turbo) and this Jekyll plugin:
Существует тысячи книг об объектно-ориентированном программировании и сотни объектно-ориентированных языков, и я считаю, что большинство (читайте “все”) из них дает нам неверное определение “объекта”. Вот почему весь мир ООП так полон заблуждений и ошибок. Их определение объекта ограничено архитектурой оборудования, с которым они работают, и поэтому оно очень примитивно и механическое. Я хотел бы предложить лучшее.
Что такое объект? Я провел небольшое исследование, и вот что я нашел:
Объект хранит свое состояние в полях и предоставляет свое поведение через методы.
Каждый объект выглядит довольно-таки как небольшой компьютер – у него есть состояние и есть операции, которые можно попросить его выполнить.
Класс - это набор данных, которые содержат значения, и методов, которые выполняют операции над этими значениями.
Объект - это некоторая область памяти, которая содержит значение некоторого типа. - The C++ Programming Language, 4-е издание, Бьярне Страуструп, стр. 40.
Объект состоит из некоторой закрытой памяти и набора операций - “Smalltalk-80” (http://amzn.to/1UhYinp), Голдберг и Робсон, стр. 6.
Что общего во всех этих определениях - это слово “содержит” (или “хранит”, “состоит”, “имеет” и т. д.). Все они считают, что объект - это коробка с данными. И именно к этой точке зрения я настоятельно противоположен.
Если мы посмотрим, как реализованы C++ или Java, такое определение объекта будет звучать технически правильно. Действительно, для каждого объекта виртуальная машина Java выделяет несколько байтов памяти, чтобы хранить атрибуты объекта там. Таким образом, мы технически можем сказать, на этом языке, что объект - это коробка с данными в памяти.
Правильно, но это всего лишь частный случай!
Давайте попробуем представить себе другой объектно-ориентированный язык, который не хранит атрибуты объектов в памяти. Запутались? Подождите минутку. Предположим, что в этом языке мы определяем объект:
Здесь vin
и engine
являются атрибутами объекта c
(это машина; давайте пока забудем о классах, чтобы сосредоточиться только на объектах). Таким образом, есть простой объект, у которого есть два атрибута. Первый - это VIN автомобиля, а второй - его двигатель. VIN является объектом v
, в то время как двигатель - e
. Для лучшего понимания, вот как бы выглядел похожий объект на Java:
Я не совсем уверен в JVM, но в C++ такой объект будет занимать ровно 25 байт памяти (при условии, что это 64-битная архитектура x86). Первые 17 байт будут заняты массивом char, а еще 8 байт - указателем на блок в памяти с объектом e. Таким образом компилятор C++ понимает объекты и преобразует их в архитектуру x86. В C++ объекты просто являются структурами данных с четко определенным распределением атрибутов данных.
В этом примере атрибуты “vin” и “engine” не равны: “vin” - это “данные”, тогда как “engine” - это “указатель” на другой объект. Я специально сделал это так, чтобы показать, что называть объектом коробкой с данными можно только с “vin”. Только когда данные находятся прямо “внутри” объекта, мы можем сказать, что объект на самом деле является коробкой для данных. С “engine” это на самом деле не так, потому что в объекте технически нет данных внутри. Вместо этого есть указатель на другой объект. Если бы у нашего объекта был только атрибут “engine”, он бы занимал всего 8 байт памяти, ни один из которых фактически не был бы занят “данными”.
Теперь вернемся к нашему новому псевдо-языку. Представим, что он очень по-другому обращается с объектами, чем C++ - он вообще не хранит атрибуты объектов в памяти. У него нет указателей, и он ничего не знает об архитектуре x86. Он просто знает, какие атрибуты принадлежат объекту.
Таким образом, в нашем языке объекты больше не являются коробками с данными ни технически, ни концептуально. Они знают, где находятся данные, но они не содержат данные. Они представляют данные, а также другие объекты и сущности. Действительно, объект c в нашем мнимом языке представляет два других объекта: VIN и двигатель.
Подводя итог, мы должны понять, что, несмотря на то что механическое определение объекта является правильным в большинстве языков программирования, существующих на рынке в данный момент, концептуально оно очень неправильно, потому что оно рассматривает объект как коробку с данными, которые слишком видимы для внешнего мира. Эта видимость заставляет нас мыслить процедурно и пытаться получить доступ к этим данным как можно больше.
Если бы мы воспринимали объект как представителя данных, а не их контейнер, мы бы не хотели получить данные как можно скорее. Мы бы понимали, что данные находятся далеко и мы не можем просто так их легко коснуться. Мы должны общаться с объектом, и то, как именно он общается с данными, не является нашей заботой.
Надеюсь, что в ближайшем будущем на рынке появятся новые объектно-ориентированные языки программирования, которые не будут хранить объекты как структуры данных в памяти, даже технически.
Кстати, вот определение объекта из моей любимой книги, Object Thinking Дэвида Уэста, стр. 66:
Что вы думаете? Это близко к тому, что я только что предложил в качестве “репрезентативного” определения?
Translated by ChatGPT gpt-3.5-turbo/42 on 2023-11-17 at 14:23