Делегирование: различия между версиями

Материал из Поле цифровой дидактики
 
Строка 26: Строка 26:


https://web.media.mit.edu/~lieber/Lieberary/OOP/Delegation/Image3.gif
https://web.media.mit.edu/~lieber/Lieberary/OOP/Delegation/Image3.gif
<nowiki>
If I'm an INSTANCE object
and I receive a message
with a SELECTOR and some  ARGUMENTS:
If the SELECTOR matches
one of the VARIABLE names
in my CLASS [or SUPERCLASS, etc.],
I return the corresponding value,
stored in myself.
Otherwise, I look for a METHOD
whose NAME matches
the SELECTOR of the message
in the list of local METHODS
of my CLASS.
If I find one,
I bind the variable SELF to myself
[the INSTANCE object].
I bind the names of
the variables of my CLASS,
[and all the variables
up the SUPERCLASS chain]
to their values in the INSTANCE.
Then I invoke the METHOD.
If there's no method
in my CLASS's METHOD list,
I try to find a method
in the SUPERCLASS,
and so on up the SUPERCLASS chain.
</nowiki>

Текущая версия на 10:07, 5 марта 2023


Описание Делегирование - свойство языка программирования использовать правила поиска метода для диспетчеризации так называемых self-calls (объектных вызовов). Это понятие было введено Либерманом в его статье 1986 года «Использование прототипических объектов для реализации общего поведения в объектно-ориентированных системах»
Область знаний Информатика
Авторы Lieberman
Поясняющее видео
Близкие понятия
Среды и средства для освоения понятия Snap!, JavaScript


Using Prototypical Objects to Implement Shared Behavior in Object Oriented Systems
https://web.media.mit.edu/~lieber/Lieberary/OOP/Delegation/Delegation.html
Реализация прототипного подхода к обмену знаниями в объектно-ориентированных системах представляет собой альтернативный механизм, называемый делегированием, появляющийся в языках акторов и нескольких объектно-ориентированных системах на основе Lisp, таких как Director, T , Orbit, и другие. Делегирование устраняет различие между классами и экземплярами. Любой объект может служить прототипом. Чтобы создать объект, который разделяет знания с прототипом, вы создаете объект-расширение, у которого есть список, содержащий его прототипы, которые могут использоваться совместно с другими объектами, и личное поведение, характерное для самого объекта. Когда объект расширения получает сообщение, он сначала пытается ответить на сообщение, используя поведение, хранящееся в его персональной части. Если личные характеристики объекта не имеют отношения к ответу на сообщение, объект пересылает сообщение прототипам, чтобы узнать, можно ли ответить на сообщение. Этот процесс пересылки называется делегированием сообщения. Слон Фред будет объектом-расширением, в личной части которого будет храниться поведение, уникальное для Фреда, а в общей части будет ссылка на прототип Клайда.
Пример с разведением понятий делегирование и наследование
Sharing Knowledge with Delegation
Image2.gif

Мы начинаем с создания прототипа объекта-пера, который имеет определенное положение на экране x=200, y=50 и поведение, отвечающее на сообщение рисования. Когда мы хотим создать новый объект пера, нам нужно только описать, чем отличается новое перо от первого, в данном случае это переменная x. Так как y один и тот же, и поведение для сообщения рисования такое же, их не нужно повторять. Метод рисования должен будет использовать значение переменной x, и важно, чтобы использовалось правильное значение x. Когда метод рисования делегируется от нового пера к старому, даже если вызывается метод рисования исходного пера, должен использоваться x нового пера. Чтобы обеспечить это, всякий раз, когда сообщение делегируется, оно также должно передаваться объекту, который первоначально получил сообщение. Это называется переменной SELF в Simula, Smalltalk и разновидностях, хотя я нахожу термин «self» немного вводящим в заблуждение, поскольку метод, первоначально определенный для одного типа объекта, часто заканчивается отправкой «self» другого типа. В терминологии акторов этот объект называется клиентом, поскольку делегируемый объект можно рассматривать как выполняющий услугу для исходного объекта. Когда перо делегирует сообщение рисования прототипу пера, оно говорит: «Я не знаю, как обрабатывать сообщение рисования. Я бы хотел, чтобы вы ответили на него, если можете, но если у вас есть дополнительные вопросы, например каково значение моей переменной x, или нужно что-то сделать, вы должны вернуться ко мне и спросить». Если сообщение делегируется дальше, все вопросы о значениях переменных или запросы на ответ на сообщения выводятся к объекту, который делегировал сообщение в первую очередь.


Sharing Knowledge with Inheritance

Давайте рассмотрим тот же пример с наследственным подходом к обмену знаниями, который используется в Simula и SmallTalk вместо делегирования. Это показано на рисунке под названием «Обмен знаниями с наследованием». При наследовании необходимо создавать объекты, представляющие классы. Чтобы сделать перо, сначала необходимо создать объект класса перо, который определяет как поведение, так и имена переменных. Отдельные перья создаются путем предоставления значений для всех переменных экземпляра класса перьев, создавая объект экземпляра. Значения для всех переменных должны быть указаны, даже если они не имеют уникальных значений в экземпляре. Никакое новое поведение не может быть привязано к отдельному перу. Расширение поведения достигается другой операцией — созданием нового подкласса. Шаг, который переходит от экземпляра к поведению, хранящемуся в его классе, выполняется с помощью «зашитого» цикла поиска в таких системах, как Simula и SmallTalk, а не путем передачи сообщений, как в подходе делегирования.

Image3.gif

If I'm an INSTANCE object and I receive a message with a SELECTOR and some ARGUMENTS: If the SELECTOR matches one of the VARIABLE names in my CLASS [or SUPERCLASS, etc.], I return the corresponding value, stored in myself. Otherwise, I look for a METHOD whose NAME matches the SELECTOR of the message in the list of local METHODS of my CLASS. If I find one, I bind the variable SELF to myself [the INSTANCE object]. I bind the names of the variables of my CLASS, [and all the variables up the SUPERCLASS chain] to their values in the INSTANCE. Then I invoke the METHOD. If there's no method in my CLASS's METHOD list, I try to find a method in the SUPERCLASS, and so on up the SUPERCLASS chain.