6. Интерфейс

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

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

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

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

{
    [тип]                Тип объекта (Сообщение)
    [объект]             Объект, которому принадлежит интерфейс
    [параметры]= {
            [интерфейс]  Ключ интерфейса
            [функция]    Ключ функции
            ...          Входные параметры вызываемой функции
    }
    [исключения]         Исключения, порождаемые вызываемой функции
    [результат]          Результат (выходные параметры) функции
}

ПРИМЕЧАНИЕ

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

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

Не очень очевидно, но в данном случае речь идёт о визуальной среде программирования, в коде же со свойствами даже нетипизованных объектов разработчик работает через интерфейс, который по сути является функцией. То есть, объект – это интерфейс, а интерфейс в свою очередь – функция.

Возникает вопрос. Функция объекта получает сообщение, которое объект, и чтобы обработать это сообщение, нужно вызвать одну из его функций, отправив новое сообщение и т.д.? Нет, просто в реализации WYCIWYC, как и в реализации любой другой среды высокого уровня, мы получаем разделение функций на два уровня: уровень реализации среды (уровень ассемблера) и уровень обеспечиваемый средой (высокий уровень). То есть, базовые понятия концепции (объект, транзакция, интерфейс, ссылка и др.) реализуются на уровне реализации среды, и между собой связаны отчасти виртуально, а на высоком уровне выглядят как нечто, сплетённое в этот самый “порочный” круг.

Надо заметить, что уровень ассемблера в WYCIWYC получается достаточно приближенным к высокому уровню. В нём нет ничего примечательного, кроме низкоуровневого занудства.

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

ПРИМЕЧАНИЕ

Почему только функций, но не свойств? Это определяется ролью класса в WYCIWYC. Именно класс формализует тип объекта, то есть набор его свойств. Интерфейс формализует функциональность.

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

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

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

Другими словами, объект в WYCIWYC - это динамический массив. Потому что статический массив является частным случаем динамического.

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

Интерфейсы объекта формализуются в классе объекта.

ПРИМЕЧАНИЕ

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

Примерно так это выглядит:

{
    [тип]=>Класс;
    [имя]=>”Класс1”;
    [свойства]=> {
            [1]=>Свойство id;
            [2]=>Свойство параметр1;
            ...
    }
    [интерфейсы]=>Интерфейс Интерфейс1;
}

ПРИМЕЧАНИЕ

Казалось бы, при множественной типизации объекта может возникнуть неопределённость в обращении к интерфейсу, если объект типизован несколькими классами, реализующими данный интерфейс. Не возникает, поскольку использование такого объекта невозможно без явного указания выбранного класса (приведения типа), а функциональность имплементируется именно в классе.

Автор: Андрей Шаройко <vanyamboe@gmail.com>