Jump to content

Делегирование (объектно-ориентированное программирование)

В объектно-ориентированном программировании делегирование относится к оценке члена ( свойства или метода ) одного объекта (получателя) в контексте другого исходного объекта (отправителя). Делегирование можно выполнить явно, передав обязанности объекта-отправителя объекту-получателю, что можно сделать на любом объектно-ориентированном языке ; или неявно, правилами поиска членов языка, который требует языковой поддержки этой функции. Неявное делегирование — это фундаментальный метод повторного использования поведения в программировании на основе прототипов , соответствующий наследованию в программировании на основе классов . Наиболее известными языками, поддерживающими делегирование на уровне языка, являются Self , который включает в себя понятие делегирования посредством понятия изменяемых родительских слотов , которые используются при поиске метода при самовызовах, и JavaScript ; см . делегирование JavaScript .

Термин делегирование также широко используется для обозначения других отношений между объектами; см . делегирование (программирование) подробнее . Понятия, которые часто путают, просто используют другой объект, точнее называемый консультацией или агрегацией ; и оценку члена одного объекта путем оценки соответствующего члена другого объекта, особенно в контексте принимающего объекта, что более точно называется пересылкой (когда объект-оболочка не передает себя обернутому объекту). [1] [2] [а] Шаблон делегирования — это шаблон проектирования программного обеспечения для реализации делегирования, хотя этот термин также широко используется для консультаций или пересылки.

Это чувство делегирования как особенности языка программирования, использующей правила поиска методов для отправки так называемых самовызовов , было определено Либерманом в его статье 1986 года «Использование прототипных объектов для реализации общего поведения в объектно-ориентированных системах».

Делегирование зависит от динамического связывания , поскольку оно требует, чтобы данный вызов метода мог вызывать различные сегменты кода во время выполнения. [ нужна ссылка ] . Он используется в macOS (и его предшественнике NeXTStep ) как средство настройки поведения программных компонентов. [3] Это позволяет реализовать такие реализации, как использование одного класса, предоставляемого ОС, для управления окнами, поскольку класс принимает делегат, специфичный для программы, и может при необходимости переопределить поведение по умолчанию. Например, когда пользователь щелкает поле закрытия, оконный менеджер отправляет делегату вызов windowShouldClose:, и делегат может отложить закрытие окна, если в содержимом окна есть несохраненные данные.

Делегирование можно охарактеризовать (и отличить от пересылки ) как позднее связывание себя : [4]

... сообщения, отправленные на self (или this) в родительской переменной «вернется» к объекту, который первоначально получил сообщение.

То есть self в определении метода в принимающем объекте статически не привязан к этому объекту во время определения (например, во время компиляции или когда функция присоединена к объекту), а скорее во время оценки он привязан к исходному объекту.

Утверждалось, что в некоторых случаях делегирование может быть предпочтительнее наследования , чтобы сделать программный код более читабельным и понятным. [5] Несмотря на то, что явное делегирование довольно широко распространено, относительно немногие основные языки программирования реализуют делегирование в качестве модели, альтернативной наследованию. Точная связь между делегированием и наследованием сложна; некоторые авторы считают их эквивалентными или одним частным случаем другого. [6]

Языковая поддержка делегирования

[ редактировать ]

В языках, которые поддерживают делегирование с помощью правил поиска методов, диспетчеризация методов определяется так же, как она определяется для виртуальных методов при наследовании: во время поиска метода всегда выбирается наиболее конкретный метод. Следовательно, именно исходный объект-получатель является началом поиска метода, даже если он передал управление какому-либо другому объекту (через ссылку делегирования, а не ссылку на объект).

Преимущество делегирования состоит в том, что оно может осуществляться во время выполнения и влиять только на подмножество сущностей определенного типа, а также может быть удалено во время выполнения. Наследование, напротив, обычно нацелено на тип, а не на экземпляры, и ограничивается временем компиляции. С другой стороны, наследование может быть статически проверено по типам, тогда как делегирование, как правило, невозможно без обобщений (хотя ограниченная версия делегирования может быть статически типобезопасной). [7] ). Делегирование можно назвать «наследованием во время выполнения конкретных объектов».

Вот пример псевдокода на C# / Java языке :

class A {
    void foo() {
        // "this" also known under the names "current", "me" and "self" in other languages
        this.bar();
    }

    void bar() {
        print("a.bar");
    }
}

class B {
    private delegate A a; // delegation link

    public B(A a) {
        this.a = a;
    }

    void foo() {
        a.foo(); // call foo() on the a-instance
    }

    void bar() {
        print("b.bar");
    }
}

a = new A();
b = new B(a); // establish delegation between two objects

Вызов b.foo() приведет к b.bar , поскольку печати this относится к исходному объекту-приемнику, b, в контексте a. В результате возникает двусмысленность this называется объектной шизофренией .

Перевод неявного this в явный параметр, вызов (в B, с a делегат) a.foo() переводится на A.foo(b), используя тип a для разрешения метода, но делегирующий объект b для this аргумент.

При использовании наследования аналогичный код (с использованием заглавных букв, чтобы подчеркнуть, что разрешение основано на классах, а не на объектах):

class A {
    void foo() {
        this.bar();
    }

    void bar() {
        print("A.bar");
    }
}

class B extends A {
    public B() {}

    void foo() {
        super.foo(); // call foo() of the superclass (A)
    }

    void bar() {
        print("B.bar");
    }
}

b = new B();

Вызов b.foo() приведет к B.bar . В этом случае, this однозначно: существует один объект, b, и this.bar() разрешается в метод подкласса.

Языки программирования в целом не поддерживают эту необычную форму делегирования как языковую концепцию, но есть несколько исключений. [ нужна ссылка ] .

Двойное наследование

[ редактировать ]

Если язык поддерживает как делегирование, так и наследование, можно реализовать двойное наследование , используя оба механизма одновременно, как в

class C extends A {
    delegationlink D d;
}

Это требует дополнительных правил поиска методов, поскольку теперь потенциально существует два метода, которые можно обозначить как наиболее специфичные (из-за двух путей поиска).

[ редактировать ]

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

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

Делегирование также было предложено для разрешения рекомендаций в аспектно-ориентированном программировании Эрнстом и Лоренцем в 2003 году.

См. также

[ редактировать ]

Различать:

Примечания

[ редактировать ]
  1. ^ Бек 1997 использует термины «простое делегирование», когда принимающий объект не имеет доступа к отправляющему объекту, и «самоделегирование», когда принимающий объект имеет доступ к отправляющему объекту; в современном языке это «пересылка» и «делегирование», используемые в этой статье.
  1. ^ Гамма и др. 1995 , «Делегация», стр. 20–21.
  2. ^ Бек 1997 , «Делегация», стр. 64–69.
  3. ^ Яблоко (20 августа 2009 г.). «Руководство по основам какао: делегаты и источники данных» . Связь с разработчиками Apple . Проверено 11 сентября 2009 г.
  4. ^ «Пересекающиеся классы и прототипы». Перспективы системной информатики: 5-я Международная конференция памяти Андрея Ершова, PSI 2003, Академгородок, Новосибирск, Россия, 9-12 июля 2003 г., Переработанные статьи . п. 38 .
  5. ^ [1] Трюгве Реенскауг , кафедра информатики Университета Осло, «Дело в пользу читаемого кода» (2007).
  6. ^ Штейн, Линн Андреа. Делегирование — это наследование . OOPSLA '87 Материалы конференции по объектно-ориентированным системам, языкам и приложениям программирования. стр. 138–146. дои : 10.1145/38807.38820 .
  7. ^ Гюнтер Книзель (19 ноября 1999 г.). «Типобезопасное делегирование для адаптации компонентов времени выполнения» . ЭКООП'99 — Объектно-ориентированное программирование . Конспекты лекций по информатике. Том. 1628. Спрингер. стр. 351–366. CiteSeerX   10.1.1.33.7584 . дои : 10.1007/3-540-48743-3_16 . ISBN  978-3-540-66156-6 . Архивировано из оригинала 4 марта 2015 г. Проверено 4 марта 2015 г. В этой статье предлагается объектно-ориентированное наследование (также известное как делегирование) в качестве дополнения к композиции объектов, основанной исключительно на пересылке. Он представляет типобезопасную интеграцию делегирования в объектную модель на основе классов и показывает, как она преодолевает проблемы, возникающие при взаимодействии компонентов на основе пересылки, как она поддерживает независимую расширяемость компонентов и непредвиденную динамическую адаптацию компонентов. {{cite book}}: CS1 maint: bot: исходный статус URL неизвестен ( ссылка )
[ редактировать ]
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: 32f5fbca378fddae1f699496b35c6101__1719799920
URL1:https://arc.ask3.ru/arc/aa/32/01/32f5fbca378fddae1f699496b35c6101.html
Заголовок, (Title) документа по адресу, URL1:
Delegation (object-oriented programming) - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)