В программировании можно сделать одно весьма интересное наблюдение: при каждом доступе к объекту какие-то процедуры всегда выполняются неявно, причем этот код не являются частью программы. Таким образом, доступ к объекту всегда является опосредованным, поскольку требуется какая-то промежуточная процедура ответственная за нахождение реального расположения представляемого объекта.
Например, если имеется ссылка на объект класса Account, описывающий счет в банке, то доступ к нему как обычно осуществляется путем вызова методов:
Account account = findAccount("Александр Савинов");
double account.getBalance(); // Доступ к объекту
Здесь вызов метода ответственен за осуществление доступа к объекту и за получение остатка на счете. Хотя при этом создается иллюзия прямого доступа путем непосредственного взаимодействия с объектом, было бы неправильно думать, что получение остатка это некая примитивная операция, выполняемая сразу после вызова метода. В действительности, если это программа на Яве, то виртуальная машина (JVM) должна разрешить ссылку в идентификатор памяти, который в свою очередь блокируется и по нему получается физический адрес в памяти. Если это удаленная ссылка, то такой вызов метода должен быть сериализован и передан по сети, используя какой-то протокол. Эта ссылка могла бы также представлять персистентный объект, и в этом случае его состояние должно быть загружено в память. Существуют также множество других примеров того, что происходит в процедуре доступа, но главное наблюдение состоит в следующем:
Всегда существует какой-то промежуточный код, выполняемый неявно за кулисами при доступа к объекту, и этот код называется темной материей программы.
Почему это называется темной материей? Поскольку этот код невидим, и о его присутствие можно узнать только опосредовано, наблюдая за вызываемыми эффектами. Присутствие темной материи в программе выводится из необходимости обосновать "недостающую функциональность", когда мы видим, что программа производит некий эффект, но ее код не содержит вызывающих его инструкций. Более того, даже если известно, что темная материя существует, в традиционном программировании не существует средств для влияния на этот уровень. Мы не можем повлиять на момент времени, когда этот (скрытый) код будет активирован. И мы не можем повлиять на то, что конкретно будет выполняться во время доступа к объектам. Этот слой находится полностью вне контроля. И здесь мы приходим к интересному, но довольно пессимистичному заключению:
Существует слой функциональности, который не может быть изменен или заменен средствами ООП.
Следует заметить, что конечно существует возможность повлиять на происходящее во время доступа к объекту путем изменения среды выполнения, компилятора, библиотек, операционной системы или аппаратной платформы. Это не изменит явно определенное поведение программы (бизнес-логику), но изменит то, как определяются ссылки, как происходит доступ к объектам и другие аспекты, которые нельзя изменить изнутри самой программы. Другими словами, погружая программу в различные среды, можно изменить неявно выполняемые промежуточные функции -- темную материю.
Но тогда в чем состоит проблема? А проблема в том, что хочется иметь возможность влиять на темную материю из самой программы, и для этой цели необходим подход к программированию, который бы трактовал ее как неотъемлемую часть программы. Хотелось бы иметь возможность разрабатывать собственную проблемно-ориентированную темную материю, которая адаптирована для целей данной программы и данной предметной области. Почему это важно? Поскольку мы принимаем следующий постулат:
Скрытые промежуточные функции, выполняемые во время доступа к объектам, столь же важны, что и явно вызываемые методы объектов, и они могут во многом или даже во всем отвечать за сложность всей программы.
Если это предположение верно, тогда фокус в программировании сдвигается в сторону разработки промежуточных функций вместо конечных методов объектов. Другими словами, смена парадигмы в том, что более важным является происходящее "между" или "в пути", чем происходящее в самом конце (вызова метода). В этом случае любой вызов метода представляется в виде последовательности промежуточных действий, где сам метод это только последний шаг. Вот несколько хорошо известных примеров функций, которые относятся к другому слою, невидимому из основного слоя бизнес-логики и поэтому трактуемые как темная материя:
- Менеджеры персистентных объектов. Здесь необходимо манипулировать персистентными объектами, как если бы они были самыми обычными объектами, путем изменения способа загрузки и управления их состоянием.
- Контейнеры объектов. Здесь необходимо иметь возможность разрабатывать проблемно-ориентированные контейнеры объектов со сложными функциями, сохраняя возможность доступа к ним, как если бы они были обычными объектами в памяти.
- Менеджеры памяти. Зачем использовать стандартную кучу, предоставляемую ОС, если для этого модуля есть множество довольно специфичных требований со стороны приложения? Было бы гораздо продуктивнее разработать собственный менеджер памяти, адаптированный для объектов этой и только этой программы.
- Проблемно-ориентированные компиляторы. Здесь необходимо изменить способ реализации ссылок и других конструкций языка. С этой целью по сути надо изменить сам компилятор, но обычно это либо невозможно, либо довольно затруднительно. Поэтому было бы интересно иметь возможность разработки компилятора/интерпретатора как неотъемлемой части самой программы.
Чтобы решить эти и многие другие проблемы, был разработан новая методология программирования --
концептно-ориентированное программирование (КОП). Темная материя в этом подходе играет центральную роль, поскольку является неотъемлемой частью программы. Программист в КОП не только может влиять на происходящее за кулисами, но более того, это является его главной задачей. Другими словами, основной задачей в КОП является создание проблемно-ориентированной среды, где будут жить объекты. Это включает такие функции как представление объектов (собственные ссылки) и доступ к объектам (собственные процедуры доступа). Функциональность такой проблемно-ориентированной среды активируется неявно путем инъекции ее функций во все внутренние объекты.
Важно, что КОП обобщает ООП, сохраняя его основные принципы и свойства. КОП вводит новую программную конструкцию, называемую
концептом и обобщающую обычные классы. Концепты в КОП существуют внутри иерархии, определяемой посредством
отношения включения, которое обобщает обычное наследование классов. Также важно, что КОП позволяет описывать сквозную функциональность, но способом, отличным от АОП (и даже во многом противоположным способом по отношению к АОП). Более того, КОП является основой для новой модели данных --
концептно-ориентированной модели (КОМ) -- значительно уменьшая несовместимость между традиционными моделями данных и программирования.
Ссылки: