Das ist eine ziemlich allgemeine Frage, aber ich habe mich heute über Delegierte Gedanken gemacht. Zu diesem Zeitpunkt habe ich nicht wirklich eine bestimmte Zeit, in der ich sie benutze oder sie nicht benutze - abgesehen von offensichtlichen Fällen, wie das Übergeben von Auswahlen von einem Picker oder Tableview. Wenn es beispielsweise eine Situation gibt, in der ich einen Verweis auf ein Objekt weitergeben kann und damit Methoden aufrufen kann, gibt es einen Grund, einen Delegierten zu implementieren? Zusammenfassend, was ist das Delegatenmuster, das in und wann verwendet werden soll, ist es besser, es NICHT zu benutzen?
Danke für die schnellen und umfassenden Antworten! Sie waren alle sehr hilfreich.
Der Vorteil des Delegatenmusters ist die lose Kopplung zwischen dem delegierenden Objekt und seinem Delegaten. Lose Kopplung verbessert die Wiederverwendbarkeit einer Klasse in anderen Kontexten.
Das delegierende Objekt muss nichts über das Objekt wissen, mit dem es kommuniziert (abgesehen von der Anforderung, dass es das Delegate-Protokoll implementiert) - insbesondere nicht seine Klasse oder welche Methoden es hat. Wenn Sie Ihre Komponente später in einem anderen Kontext wiederverwenden oder mit einem anderen Objekt einer anderen Klasse kommunizieren möchten, muss dieses Objekt nur das Delegate-Protokoll implementieren. Das delegierende Objekt muss überhaupt nicht geändert werden.
Es gibt natürlich auch einen Nachteil, und das bedeutet, dass ein bisschen mehr Code benötigt wird und der Code, den Sie schreiben, nicht so explizit ist und daher etwas schwieriger zu verstehen ist. Ob sich dieser (meist kleine) Kompromiss lohnt, hängt von Ihrem Anwendungsfall ab. Wenn die beiden Objekte ohnehin eng gekoppelt sind und die Wahrscheinlichkeit einer Wiederverwendung in der Zukunft gering ist, ist die Verwendung des Delegatenmusters möglicherweise übertrieben.
Siehe diese Diskussion
Ein Delegat ermöglicht einem Objekt, Nachrichten an ein anderes Objekt zu senden, wenn ein Ereignis eintritt.
Vorteile
Sehr strenge Syntax. Alle zu hörenden Ereignisse sind klar definiert in das Delegiertenprotokoll.
Kompilieren Sie Zeit Warnungen / Fehler, wenn eine Methode nicht wie von einem Delegierten implementiert werden sollte.
Nur im Rahmen des Controllers definiertes Protokoll.
Sehr nachvollziehbarer und leicht zu identifizierender Steuerungsfluss innerhalb einer Anwendung.
Möglichkeit, dass mehrere Protokolle einen Controller mit jeweils unterschiedlichen Delegierten definieren.
Es ist kein Objekt eines Drittanbieters erforderlich, um den Kommunikationsprozess aufrechtzuerhalten / zu überwachen.
Möglichkeit, einen zurückgegebenen Wert von einer aufgerufenen Protokollmethode zu erhalten. Dies bedeutet, dass ein Delegierter helfen kann, Informationen zurückzugeben zu einem Controller.
Nachteile
Viele Codezeilen müssen definiert werden: 1. die Protokolldefinition, 2. die Delegate-Eigenschaft im Controller und 3. die Implementierung der Delegierten-Methodendefinitionen innerhalb des Delegaten selbst.
Es muss darauf geachtet werden, dass Delegaten bei der Freigabe von Objekten korrekt auf Null gesetzt werden. Andernfalls kann es zu Speicherabstürzen kommen, wenn Methoden bei freigegebenen Objekten aufgerufen werden.
Obwohl es möglich ist, kann es schwierig sein und das Muster eignet sich nicht wirklich dazu, mehrere Delegaten desselben Protokolls in einem Controller zu haben (mehrere Objekte über dasselbe Ereignis zu sagen)
Der "Anwendungsfall" für die Delegierung ist ziemlich genau der gleiche wie für die Vererbung, nämlich die Erweiterung eines Klassenverhaltens auf eine polymorphe Art.
So definiert die wikipedia Delegation:
In der Softwareentwicklung ist das Delegierungsmuster ein Entwurfsmuster in der objektorientierten Programmierung, bei dem ein Objekt diese Aufgabe an ein zugehöriges Hilfsobjekt delegiert, anstatt eine der angegebenen Aufgaben auszuführen. Es gibt eine Inversion of Responsibility, bei der ein als Delegat bekanntes Hilfsobjekt die Aufgabe hat, eine Aufgabe für den Delegator auszuführen. Das Delegationsmuster ist eines der grundlegenden Abstraktionsmuster, die anderen Softwaremustern wie Komposition (auch als Aggregation bezeichnet), Mixins und Aspekten zugrunde liegen.
Es gibt offensichtlich viele Unterschiede zwischen Delegierung und Vererbung, aber die größte ist IMO, dass die Vererbung eine feste (aka, Kompilierzeit) Beziehung zwischen zwei Klassen ist, während die Delegierung zur Laufzeit definiert werden kann ( in Sprachen, die dies unterstützen). Auf der anderen Seite bietet Vererbung eine bessere Unterstützung für Polymorphismus.
Delegation ist ein großes Thema (wie Vererbung ist), und Sie können viel darüber lesen. Am Ende entscheiden Sie, ob die Verwendung von Delegierung oder Vererbung dazu führt, zu entscheiden, ob Sie eine "ist-a" - oder eine "hat-a" -Beziehung haben wollen. Daher ist es nicht so einfach, Richtlinien dafür aufzulisten.
Für mich ist die Entscheidung, einen Delegierten zu erstellen, im Wesentlichen folgende Beobachtung:
mein Code stellt eine Menge homogener Verhaltensweisen dar (homogen bedeutet hier, dass man erkennen kann, dass sie eine gemeinsame "Natur" haben);
Diese Verhaltensweisen können für bestimmte Fälle (wie in, ersetzt durch alternative Verhaltensweisen) "angepasst" werden.
Dies ist meine persönliche Ansicht und eine Beschreibung der Art und Weise, wie ich "Delegations" -Muster erkennen kann. Es hat wahrscheinlich viel damit zu tun, dass meine Programmierdisziplin stark vom Prinzip des Refactoring geprägt ist.
Wirklich, IMO, Delegation ist eine Möglichkeit, "Anpassungspunkte" für Ihre Klasse zu definieren. Wenn Sie zum Beispiel einen abstrakten Workflow haben, bei dem Sie bei jedem Schritt abhängig von bestimmten Bedingungen etwas unternehmen; und außerdem könnten diese konkreten Maßnahmen durch andere von anderer Art ersetzt werden, dann sehe ich dort die Chance einer Wiederverwendung durch Delegierung.
Hoffe, das hilft.
Tags und Links objective-c delegates