В программной инженерии шаблон делегирования — это объектно-ориентированный шаблон проектирования , который позволяет композиции объектов достигать того же повторного использования кода, что и наследование .
В делегировании объект обрабатывает запрос, делегируя его второму объекту ( делегату ). Делегат является вспомогательным объектом , но с исходным контекстом . При поддержке делегирования на уровне языка это делается неявно, имея self
в делегате ссылку на исходный (отправляющий) объект, а не на делегата (принимающий объект). В шаблоне делегата это вместо этого достигается явной передачей исходного объекта делегату в качестве аргумента метода. [1] «Делегирование» часто используется в широком смысле для обозначения отдельной концепции пересылки , где отправляющий объект просто использует соответствующий член принимающего объекта, оцененный в контексте принимающего объекта , а не исходного объекта.
В этой статье для двух объектов используется термин «отправляющий объект/принимающий объект», а не «принимающий объект/делегат», подчеркивая, какие объекты отправляют и получают вызов делегирования, а не исходный вызов.
Во введении к работе Гаммы и др. 1994 г. делегирование определяется как:
Делегирование — это способ сделать композицию такой же мощной для повторного использования, как наследование [Lie86, JZ91]. При делегировании в обработке запроса участвуют два объекта: принимающий объект делегирует операции своему делегату . Это аналогично подклассам, откладывающим запросы родительским классам. Но при наследовании унаследованная операция всегда может ссылаться на принимающий объект через
this
переменную-член в C++ иself
Smalltalk. Чтобы достичь того же эффекта с делегированием, получатель передает себя делегату, чтобы делегированная операция ссылалась на получателя. [2]
В приведенном ниже примере (с использованием языка программирования Kotlin ) класс Window делегирует вызов area()
своему внутреннему объекту Rectangle (своему делегату).
класс Rectangle ( val width : Int , val height : Int ) { fun area () = width * height } class Window ( val bounds : Rectangle ) { // Делегирование fun area () = bounds . area () }
В некоторых языках имеется специальная встроенная поддержка делегирования. Например, в языке программирования Kotlinby
ключевое слово [3] делегирует полномочия интерфейсу другого объекта:
интерфейс ClosedShape { забавная область (): Int } класс Rectangle ( val width : Int , val height : Int ) : ClosedShape { переопределить забавную область () = ширина * высота } // Реализация ClosedShape окна делегирует полномочия реализации Rectangle, которая ограничивает класс Window ( private val bounds : Rectangle ) : ClosedShape by bounds