agorlov.github.io

My homepage

View My GitHub Profile

Перевод поста Егора Бугаенко Who is an object? от 14.07.2016

Оригинал: http://www.yegor256.com/2016/07/14/who-is-object.html

Объект, это кто?

keywords: ООП, OOP, object, объект, объектно ориентированное программирование

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

Поэтому ООП мир полон заблуждений и ошибочных представлений.

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

Что такое объект? Я провел небольшое исследование и вот, что я нашел:

Что общего во всех этих определениях — слово содержит (или хранит, состоит и т.д.). Они все думают, что объект это коробка с данными. И это та точка зрения, с которой я в корне не согласен.

Если посмотреть как реализован C++ или Java, такое определение объекта звучит технически корректно. Действительно, для каждого объекта виртуальная машина Java выделяет какое-то кол-во байт в памяти, чтобы хранить там поля объекта. Таким образом, технически, мы можем сказать, что для этих языков объект это коробка с данными в памяти.

Все верно, но это только частный случай!

Давайте попробуем представить иной объектно-ориентированный язык, который не хранит поля объекта в памяти. Смущены? Потерпите меня еще минуту. Объявим объект на этом языке:

c {
  vin: v,
  engine: e
}

Тут vin и engine поля объекта c (это машина; забудем пока о классах, чтобы сосредоточиться на объектах). Таким образом, есть простой объект с двумя полями. Первое это VIN автомобиля, второе это двигатель. VIN это объект v, а двигатель это e. Чтобы легче было понять, вот как подобный объект выглядит на Java:

char[] v = {'W','D','B','H',...'7','2','8','8'}; // 17 chars
Engine e = new Engine();
Car c = new Car(v, e);

Я не совсем уверен как в JVM, но в C++ такой объект займет ровно 25 байт в памяти (для архитектуры x86, 64 бита). Первые 17 байт займет массив знаков и оставшиеся 8 байт указатель на блок в памяти, занимаемый объектом e. Вот так компилятор C++ понимает объекты и транслирует их в архитектуру x86. В C++, объекты это просто структуры данных с четко определенными полями данных.

В этом примере поля vin и engine отличаются: vin это данные, а engine это указатель на другой объект. Я намеренно так сделал, чтобы продемонстрировать, объект становится коробкой с днными при наличии vin. Только наличие данных внутри объекта позволяет называть его коробкой с данными. С полем engine немного иначе, технически внутри объекта нет данных двигателя. Есть только указатель на другой объект. Если бы наш объект содержал бы только поле engine, он занял бы всего 8 байт в памяти и ни одного байта данных.

Вернемся к нашему псевод-языку и представим, что он представляет объекты не так как в C++ — он вообще не хранит поля объектов в памяи. В нем нет указателей и он ничего не знает о x86 архитектуре. Он лишь знает как-то, что поля относятся к объекту.

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

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

Эта доступность провоцирует нас думать процедруно и напрямую обращаться к данным.

badge

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

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

Кстати, вот определение объекта из моей любимой кники, “Object Thinking” Дэвида Уэста (стр. 66):

Объект является эквивалентом кванта, из которых строится Вселенная.

Как вы думаете, похоже ли оно на мое определение представителя?