- Delegation (Softwareentwicklung)
-
Die Delegation (vom lateinischen delegare für „hinschicken“, „anvertrauen“ oder „übertragen“) ist in der Softwareentwicklung ein Lösungskonzept zur losen Bindung eines stellvertretenden Anbieters von Funktionalität und eines Nutzers derselben. Diese Bindung findet nur zur Laufzeit statt, wobei der Nutzer keine Kenntnis von der konkreten Realisierung erhält.
Inhaltsverzeichnis
Hintergrund
Im Bereich der objektorientierten Programmierung kann in manchen Fällen durch Vererbung oder gängige Beziehungsarten wie die Interaktion oder Aggregation keine zufriedenstellende Trennung von Dienstanbieter und -nutzer garantiert werden. Alle zuvor genannten Konzepte erfordern eine Bindung schon vor der Laufzeit. Wird der Dienstanbieter verändert, können die Nutzer diesen unter Umständen nicht mehr nutzen, da sie seine Schnittstellen nicht mehr verstehen. Die Delegation bietet in solchen Fällen eine für die Nutzer konstante Schnittstelle und delegiert die Aufrufe an eine darunter liegende Schicht. In der Informatik wird dieses unter anderem in der Forschung zur Künstlichen Intelligenz seit langem verwendet.
- In den meisten Fällen bezieht sich die Delegation auf ein Sprachelement, welches die Regeln der Funktionsaufrufe für sogenannte „self-calls“ (englisch für „Selbstaufrufe“) nutzt, wie sie Lieberman in seiner Veröffentlichung „Using Prototypical Objects to Implement Shared Behavior in Object Oriented Systems“[1] definiert. Die Delegation als Sprachelement unterstützt die prototypenbasierte Programmierung.
- In seiner ursprünglichen Verwendung bezieht sich die Delegation auf Objekte, welche sich wiederum aufeinander beziehen, um eine spezifizierte Menge an Funktionalitäten bereitzustellen.
Als Entwurfsmuster
In den Entwurfsmustern der Gang of Four (engl. Viererbande) wird statt des allgemeinen Delegate vom Proxy oder dem Adapter gesprochen. Im Allgemeinen kennt der Nutzer eines Dienstes nur die Schnittstelle zu einem Vertreter der Diensterbringung und das Protokoll, d.h. wie die Schnittstelle benutzt werden muss. Der Vertreter verbirgt die Diensterbringung hinter mehr oder weniger dynamischen Verfahren zur Ermittlung eines konkreten Dienstleisters. Eine Aufbereitung der übergebenen Daten ist möglich. Außerdem kann der Vertreter Fehler- und Ausnahmesituationen erkennen und sogar geeignete Maßnahmen wie die Auswahl von Alternativen der Delegation bieten.
In komplexen Anwendungen kann diese Überantwortung von Aufgaben den gesamten Lebenszyklus aller Objekte betreffen, um ein Minimum an Bindung zu erreichen und damit ein Maximum an Portabilität. Das beginnt mit der Konstruktion einer Instanz aus einer Klasse, der Auflösung von Abhängigkeiten der Instanz, der Aufgabenbewältigung und endet mit der Bereinigung des durch die Instanziierung belegten Speichers inkl. der Behandlung von Ausnahmesituationen, Wiederverwendung von Instanzen uvm. So interagiert der Dienstnutzer in einer JEE (Java Enterprise Edition) nur mit einem Interface, dessen konkrete Realisierung wie auch tiefer liegende Abhängigkeiten bspw. zu Verarbeitungslogik oder Persistenzmechanismen vor ihm verborgen werden.
Als Sprachelement
Die einfache Definition der Delegation ist, dass die Funktionsaufrufe das identische Verhalten wie virtuelle Funktionsaufrufe aufweisen, es wird immer die am meisten spezifizierte Funktion aufgerufen. Respektive ist es die Originalfunktion, welche den Anfang des sogenannten lookups (englisch für „Nachschlag“) darstellt, selbst wenn es die Kontrolle einem anderen Objekt übertragen hat. Die Delegation besitzt den Vorteil, dass sie zur Laufzeit erfolgen kann. Sie kann auch während der Laufzeit wieder rückgängig gemacht werden. Die Vererbung könnte auch Funktionsaufrufe derart zusammenfassen, zielt auf den Typ einer Entität und ist auf die Kompilierungszeit beschränkt. Der Nachteil der Delegation ist, dass sie nicht vollständig als typsicher betrachtet werden kann (G. Kniesel zeigte allerdings, dass eine beschränkte Version typsicher sein kann). Die Delegation kann auch als „Laufzeitvererbung für spezifische Objekte“ bezeichnet werden.
Beispiel in Java/C# Pseudocode:
class A { void foo() { this.bar() // "this" ist auch als "current", "me" und "self" in anderen Programmiersprachen bekannt } void bar() { print("a.bar") } } class B { private A a; // delegationslink public B(A a) { this.a = a; } void foo() { a.foo() // rufe foo() über die a-Instanz auf } void bar() { print("b.bar") } } a = new A() b = new B(a) // erstelle eine Delegation zwischen zwei Objekten b.foo() // Aufruf der Methode zur Delegierung der Ausgabe
Der Aufruf
b.foo()
hat zur Folge, dass a.bar ausgegeben wird da die Klasse B die Funktion foo() an das übergebene Objekt der Klasse a delegiert.
Programmiersprachen unterstützen normalerweise das Konzept der Delegation nicht, allerdings existieren ein paar Ausnahmen: ECMAScript, Self, G.Kniesels Lava, sowie das Tcl Objektsystem Snit. Lava benutzt einen expliziten Delegationslink, welcher nie null sein kann und sich nie während der Lebenszeit eines Objektes ändert. Self besitzt das Sprachelement der expliziten parent slots, welche sich zur Laufzeit verändern können. Da viele parent slots vorhanden sind, besitzt Self grundsätzlich die Fähigkeit der mehrfachen Vererbung. Die Delegation in Self wird durch das Sprachelement mutable parent slots realisiert. Dieses Konzept wird in einer Reihe von Arbeiten in der Literatur über objektorientierter Systementwicklung erläutert, allerdings ist zu beachten, dass keine einheitliche Terminologie existiert. Wie auch bei der unten beschriebenen dualen Verebung bedarf es eines sorgsam entworfenen Funktions-lookup Schemas.
Duale Vererbung
Wenn die Programmiersprache die Delegation und die Vererbung unterstützt, kann man die duale Vererbung einsetzen, indem man beide Mechanismen gleichzeitig benutzt:
class C extends A { delegationlink D d }
In diesem Beispiel sind zusätzliche Regeln bezüglich des lookup der Funktionen nötig, da zwei Funktionen als potentiell am meisten spezifiziert bezeichnet werden können. Dies wird in K. Graversen's Promovierungsthese bezüglich Regeln ausgearbeitet.
Verwandte Bereiche
Delegation kann als low-level Mechanismus beschrieben werden welcher dazu dient Code zwischen zwei Entitäten auszutauschen, insbesondere rollenorientierte Programmiersprachen benutzen die Delegation. Vornehmlich ältere Programmiersprachen geben an Delegation zu beherrschen obwohl sie faktisch die Aggregation umsetzen, was mit den unterschiedlichen Definitionen der Delegation zusammenhängt.
Seit neuerer Zeit wird die Forschung zu verteilter Delegation im Bereich der Suchmaschinen betrieben. Clients einer Suchmaschine benutzen eine verteilte Entität welche die besten Suchergebnisse sowie allgemeine, wiederbenutzbare Funktionalität zur Verfügung stellt.
Die Delegation wurde als Lösungsansatz in der aspektorientierten Programmierung von Ernst und Lorenz im Jahr 2003 vorgeschlagen.
Die Delegation stellt in prototypenbasierten Programmiersprachen wie JavaScript eine fundamentale Programmiertechnik dar.
Siehe auch
- Adapter (Entwurfsmuster)
- Delegat (.NET) .NET-Sprachen bieten eine Möglichkeit, die es Objekten erlaubt, Funktionen als eine Form von typsicheren Funktionszeigern aufzurufen. Solche Objekte werden auch als Delegate bezeichnet, ihre Funktionsweise entspricht allerdings nicht der in diesem Artikel beschriebenen Form der Delegation.
- Hook (EDV)
- Liskovsches Substitutionsprinzip
- Wrapper (Software)
Weblinks
- The Darwin Project - Die Lava Programmiersprache und allgemeine Artikel über die Delegation
- Schnelle Delegate in C++
- Eine neue Art Delegate in C++ zu implementieren
- PerfectJPattern Open Source Project Stellt eine wiederbenutzbare Java-implementation von Delegaten zur Verfügung.
Einzelnachweise
- ↑ Using Prototypical Objects to Implement Shared Behavior in Object Oriented Systems (englisch) – Veröffentlichung von Henry Lieberman beim MIT, aus dem Jahr 1986
Wikimedia Foundation.