Ein WWDC 2015 Sitzungsvideo beschreibt die Idee der protokollorientierten Programmierung und ich möchte diese Technik in meinen zukünftigen Apps übernehmen. Ich habe in den letzten Tagen mit Swift 2.0 herumgespielt, um diese neue Herangehensweise zu verstehen, und ich versuche, es mit der Delegate-Muster .
Ich habe zwei Protokolle, die die grundlegende Struktur des interessanten Teils meines Projekts definieren (der Beispielcode ist Unsinn, beschreibt aber das Problem):
1) Ein Delegierungsprotokoll , das einige Informationen ähnlich dem UITableViewController-Protokoll dataSource bereitstellt:
%Vor%2) Ein Schnittstellenprotokoll der Entität, die etwas mit der Information von oben tut (hier kommt die Idee eines "Protocol-First" -Ansatzes ins Spiel):
%Vor%In Bezug auf die tatsächliche Implementierung des Datenprozessors kann ich nun zwischen Enums, Strukturen und Klassen wählen. Es gibt verschiedene Abstraktionsebenen für die Art und Weise, wie ich die Informationen verarbeiten möchte. Deshalb scheinen Klassen am besten zu passen (ich möchte dies jedoch nicht zu einer ultimativen Entscheidung machen, da sie sich in zukünftigen Anwendungsfällen ändern könnte). Ich kann eine Basis-Prozessor-Klasse definieren, auf der ich mehrere fallspezifische Prozessoren aufbauen kann (nicht möglich mit structs und enums):
%Vor%Bis hier funktioniert alles wie ein Zauber. In Wirklichkeit sind die spezifischen Datenprozessoren jedoch eng an die Werte gebunden, die verarbeitet werden (im Gegensatz zum Basisprozessor, für den dies nicht richtig ist), so dass ich das integrieren möchte ValueProvider direkt in die Unterklasse (zum Vergleich: UITableViewControllers sind oft ihre eigene dataSource und Delegate).
Zuerst dachte ich über das Hinzufügen einer Protokollerweiterung mit einer Standardimplementierung nach:
%Vor%Dies würde wahrscheinlich funktionieren, wenn ich nicht die BaseDataProcessor-Klasse hätte, die ich nicht wertgebunden machen möchte. Unterklassen, die von BaseDataProcessor und erben, übernehmen ValueProvider jedoch scheinbar intern, sodass dies keine Option ist.
Ich experimentierte weiter und endete damit:
%Vor%Was kompiliert und auf den ersten Blick scheint zu tun, was ich will. Dies ist jedoch keine Lösung, da es einen Referenzzyklus erzeugt, der auf einem Swift-Spielplatz zu sehen ist:
%Vor%Eine weitere Option könnte sein, den Protokolldefinitionen Klasseneinschränkungen hinzuzufügen. Dies würde jedoch den POP-Ansatz nach meinem Verständnis durchbrechen.
Abschließend denke ich, meine Frage läuft auf Folgendes hinaus: Wie machen Sie die protokollorientierte Programmierung und das Delegiertenmuster zusammen, ohne sich auf Klassenbeschränkungen während des Protokollentwurfs zu beschränken?
Es stellt sich heraus , dass die Verwendung von autorespool in Playgrounds nicht für die Proof-Referenz geeignet ist Fahrräder. Tatsächlich gibt es keinen Referenzzyklus im Code, wie man sehen kann, wenn der Code als CommandLine-App ausgeführt wird. Die Frage bleibt, ob dies der beste Ansatz ist. Es funktioniert, sieht aber etwas hacky aus.
Ich bin auch nicht glücklich mit der Initialisierung von BaseDataProcessors und SpecificDataProcessors . BaseDataProcessors sollte keine Implementierungsdetails der Unterklassen w.r.t. kennen. valueProvider und Unterklassen sollten diskret sein, dass sie valueProvider sind.
Vorläufig habe ich das Initialisierungsproblem wie folgt gelöst:
%Vor%Wenn Sie eine bessere Idee haben, lassen Sie es mich wissen:)
Tags und Links ios design-patterns swift protocols delegates