Чем ОО-подход отличается от ПП-подхода?
June 26, 2022
Что такое ООП? Наследование, инкапсуляция и полиморфизм? У Алана Кея (автора термина) другое мнение:
OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things. It can be done in Smalltalk and in LISP. There are possibly other systems in which this is possible, but I’m not aware of them.
ООП для меня означает только обмен сообщениями, локальное сохранение, защиту и скрытие состояния процесса и максимально позднее связывание всего. Это можно сделать в Smalltalk и LISP. Возможно, есть и другие системы, в которых это возможно, но я о них не знаю.
Ещё одна его цитата:
I made up the term 'object-oriented', and I can tell you I didn’t have C++ in mind.
На самом деле это я придумал термин “объектно-ориентированный” и я могу сказать вам, что я не имел С++ ввиду.
На самом деле определений объектно-ориентированности десятки. Поэтому я решил завести своё собственное определение с состояниями и протоколами 😂
И так, барабанная дробь…
- Объектно-ориентированный подход -
- это подход к разработке программ, в котором базовым блоком является объект.
Не торопитесь клеймить меня кэпом и закрывать пост - мякотка будет впереди.
Теперь давайте разбираться, что такое объект. Тут в целом в индустрии вроде есть консенсус, хотя даже тут я не могу найти авторитетный источник с определением термина. Но в целом, кажется, такую формулировку никто не будет особо оспаривать:
- Объект -
- это сущность, обладающая идентичностью, состоянием и поведением.
Казалось бы всё ок, но что такое "поведение"? Если туда копнуть, там снова будет куча интерпретаций. В частности, многие запишут в объекты, штуковину, у котрой из поведения только геттеры и сеттеры. Я же скажу, что такая штуковина является структурой данных, а не объектом.
В чём между ними разница? Для того чтобы ответить на этот вопрос, нам сначала придётся разобраться с термином "пространство состояний объекта".
Пространство состояний - это множество всех состояний, в которых может находится объект. Определяется оно как декартово произведение пространств состояний полей объекта. Рекурсия заканчивается на примитивных типах и массивах. Звучит сложно, но на самом деле просто.
Давайте возьмём класс определяющий самое простое из возможных пространств состояний для своих объектов:
data class Flag(var enabled: Boolean)
Пространство состояний объектов этого класса состоит из двух точек - true и false.
Теперь возьмём объект посложнее:
data class NonNegativePoint1D(var x: Byte)
Тут у нас уже 256 точек - длина диапазона UByte.
Можно эти классы объединить и получить пространство "мощностью" в 512 точек:
data class Point1D(
var x: NonNegativePoint1D,
var positive: Flag
)
Наконец, это пространство можно сделать фактически бесконечным:
data class NamedPoint1D(
var p: Point1D,
var name: String
)
Размер этого пространства: 512 * (2^31 (максимальный размер массива в JVM) * 2^16 (мощность пространства состояний объекта Char)) = 7,205759404×10¹⁶. Для потока-сознания-поста не охота заморачиваться, но полагаю для перечисления всех элементов этого пространства на современном компьютере потребуется пара жизней нашей вселенной.
Так вот объект отличается от структуры данных тем, что обладает эксклюзивным доступом к своему состоянию и использует это для сокращения своего пространства состояний.
И так как всё приведённые выше примеры позволяют своим клиентам установить в свои поля любую комбинацию значений через сеттеры - эти штуки являются структурами данных, а программы, содержащие только подобные им штуки, написаны в процедурном, а не объектом стиле.
Поэтому я предлагаю следующее определение:
- Объект -
- это сущность, которая обладает состоянием и определяет протокол его изменений.
Возможность обеспечить эксклюзивный доступ к состоянию и его полноценное использование для определения протокола имеет больше значение для поддерживаемости программ.
Это существенно упрощает понимание программ, благодаря тому, что:
Непосредственно сокращает пространство возможных состояний объекта Исключает возможность случайного помещения объекта в недопустимое состояние Фиксирует и делает явным список возможных переходов между состояниями
На мой взгляд именно это отличает оо-подход от пп-подхода.