Русская Википедия:Шаблон делегирования
Делегирование (Шаблон:Lang-en) — основной шаблон проектирования, в котором объект внешне выражает некоторое поведение, но в реальности передаёт ответственность за выполнение этого поведения связанному объекту. Шаблон делегирования является фундаментальной абстракцией, на основе которой реализованы другие шаблоны - композиция (также называемая агрегацией), примеси (mixins) и аспекты (aspects).
Плюсы
Возможность изменить поведение конкретного экземпляра объекта вместо создания нового класса путём наследования.
Минусы
Этот шаблон обычно затрудняет оптимизацию по скорости в пользу улучшенной чистоты абстракции.
Применимость
Java
Хотя делегирование не поддерживается языком Java, его поддержка присутствует во многих средах разработки[1].
Примеры
Java
Простой пример
В этом примере на языке Java, класс B
имеет метод-заглушку (method stub), который передаёт методы foo()
и bar()
классу A
. Класс B
делает вид, что он имеет атрибуты класса A
.
Шаблон:Hider hiding
Сложный пример
Используя интерфейсы, делегирование можно осуществить более гибко и c защитой типов (typesafe). В этом примере, класс C
может делегировать либо классу A
либо классу B
. Класс C
имеет методы для переключения между классами A
и B
. Включение расширения implements улучшает безопасность типа, потому что каждый класс должен выполнять методы в интерфейсе. Основным недостатком является большее количество кода.
Приведем пример. Допустим, нужно реализовать таймер таким образом, чтобы через определённое количество времени вызывалась некоторая функция. Программист таймера хочет предоставить задание функции пользователям своего класса (другим программистам). Шаблон:Hider hiding
C++
Сложный пример
Этот пример — это версия на C++ сложного примера на Java, приведённого выше. Так как C++ не имеет конструкции интерфейса, ту же самую роль играет полностью абстрактный класс. Преимущества и недостатки в основном те же самые, что и в примере на Java. Шаблон:Hider hiding
C#
Нетривиальный пример
Это пример случая, часто встречающегося в практике. Стоит задача создать класс для хранения списка сотрудников. Данные каждого сотрудника хранятся в объекте класса Employee. Есть уже готовый и стандартный класс для хранения списка объектов Employee. В нём уже реализованы механизмы для работы со списком (к примеру — выделение памяти, добавление и удаление из списка). Наследование класса списка сотрудников от класса списка объектов здесь неприемлемо, потому как мы получим все методы (даже те, которые нас не интересуют). Кроме того нам придётся в некоторых случаях производить приведение типов. Самый элегантный выход из этого случая — делегировать классу списка сотрудников часть методов класса списка объектов. В правилах ООП лучше всего список объектов представить частным (приватным) методом списка сотрудников. В данном случае доступ к списку возможен через индексатор. Шаблон:Hider hiding Шаблон:Hider hiding
Objective-C 2.0
Простой пример
Object Pascal
Простой пример
Нетривиальный пример
Этот пример — это версия на Object Pascal нетривиального примера, приведённого выше. Шаблон:Hider hiding К сожалению, не все программисты применяют шаблон делегирования. Например, фирма Borland (разработчик среды программирования Delphi) в своей стандартной библиотеке классов наследовала вышеупомянутый класс списка объектов TObjectList от класса списка указателей TList. Это вызвало недовольство среди некоторых опытных программистов.
PHP5
Простой пример
Этот пример — это версия на PHP простого примера на Java, приведённого выше. Шаблон:Hider hiding
Сложный пример
Этот пример — это версия на PHP сложного примера на Java, приведённого выше. Шаблон:Hider hiding
Нетривиальный пример
Этот пример — это версия на PHP нетривиального примера, приведённого выше. Шаблон:Hider hiding
Python
Простой пример
Исходный текст на языке Python
#coding: utf-8
#python 3
class A:
def f(self):
print('A : вызываем метод f')
def g(self):
print('A : вызываем метод g')
class C:
def __init__(self):
self._A = A
def f(self):
return self._A.f(self)
def g(self):
return self._A.g(self)
c = C()
c.f() #A: вызываем метод f
c.g() #A: вызываем метод g
JavaScript
Простой пример
Сложный пример
Нетривиальный пример
VB.NET
Сложный пример
Нетривиальный пример
См. также
Примечания
Литература
- Джулиан Бакнелл «Фундаментальные алгоритмы и структуры данных в Delphi». Изд. DiaSoft 2003 год
- Гранд М. «Шаблоны проектирования в Java». 2004
- Брюс Эккель "Философия Java". Изд. "Питер" 2016 год
Шаблон:Типы шаблонов проектирования Шаблон:Rq
- Страницы, использующие устаревший тег source
- Русская Википедия
- Статьи с примерами кода JavaScript
- Статьи с примерами кода C++
- Статьи с примерами кода C Sharp
- Статьи с примерами кода PHP
- Статьи с примерами кода Object Pascal
- Страницы, где используется шаблон "Навигационная таблица/Телепорт"
- Страницы с телепортом
- Википедия
- Статья из Википедии
- Статья из Русской Википедии