wake-up-neo.com

Was ist die beste Methode, um Swift-Dateien zu benennen, die vorhandenen Objekten Erweiterungen hinzufügen?

Es ist möglich, Erweiterungen zu vorhandenen Swift-Objekttypen hinzuzufügen, indem Erweiterungen verwendet werden, wie in der Sprachspezifikation beschrieben.

Daher ist es möglich, Erweiterungen zu erstellen, z.

extension String {
    var utf8data:NSData {
        return self.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
    }
}

Was ist jedoch die beste Benennungspraxis für Swift-Quelldateien, die solche Erweiterungen enthalten? 

In der Vergangenheit bestand die Konvention darin, extendedtype+categoryname.m für den Typ Objective-C Zu verwenden, wie in der Objective-C-Leitfaden beschrieben. Das Swift-Beispiel hat jedoch keinen Kategorienamen, und es wäre nicht angebracht, String.Swift zu nennen.

Die Frage ist also: Wie soll die Swift-Quelldatei angesichts der obigen Erweiterung String heißen?

125
AlBlue

Die meisten Beispiele, die ich gesehen habe, ahmen den Objective-C-Ansatz nach. Die Beispielerweiterung oben wäre:

String+UTF8Data.Swift

Die Vorteile bestehen darin, dass die Namenskonvention es verständlich macht, dass es sich um eine Erweiterung handelt und welche Klasse erweitert wird.

Das Problem bei der Verwendung von Extensions.Swift oder sogar StringExtensions.Swift besteht darin, dass es nicht möglich ist, den Zweck der Datei anhand ihres Namens zu ermitteln, ohne sich den Inhalt anzusehen.

Die Verwendung des xxxable.Swift-Ansatzes, wie er von Java verwendet wird, funktioniert für Protokolle oder Erweiterungen, die nur Methoden definieren. Das obige Beispiel definiert jedoch ein Attribut, so dass UTF8Dataable.Swift wenig grammatikalisch sinnvoll ist.

149
picciano

Es gibt keine Swift-Konvention. Halte es einfach:

StringExtensions.Swift

Ich erstelle eine Datei für jede Klasse, die ich erweitern möchte. Wenn Sie eine einzige Datei für alle Erweiterungen verwenden, wird daraus schnell ein Dschungel.

5
Mike Taverne

Meine Einstellung ist "Extension_" am Anfang der Datei. (Ich füge alle zugehörigen Erweiterungen in derselben Datei zusammen.)

Auf diese Weise befinden sich alle Erweiterungsdateien alphabetisch im Verzeichnis meiner App und im Xcode-Navigator. Im Navigator kann ich sie natürlich auch gruppieren.

Eine String-bezogene Erweiterung würde also in Extension_String.Swift gehen.

1
leanne

Ich bevorzuge StringExtensions.Swift, bis ich zu viele Dinge hinzugefügt habe, um die Datei in etwas wie String+utf8Data.Swift und String+Encrypt.Swift zu teilen.

Eine weitere Sache: Wenn Sie ähnliche Dateien in einer Datei kombinieren, wird Ihr Gebäude schneller. Siehe Optimierung der Swift-Build-Zeiten

1
DawnSong

Wenn Sie über ein vom Team festgelegtes Set an allgemeinen und verschiedenen Verbesserungen verfügen, können Sie diese als Extensions zusammenfassen. Swift funktioniert als First-Level-Lösung von Keep-It-Simple. Wenn jedoch Ihre Komplexität zunimmt oder die Erweiterungen stärker involviert sind, ist eine Hierarchie erforderlich, um die Komplexität zu kapseln. Unter diesen Umständen empfehle ich die folgende Praxis mit einem Beispiel.

Ich hatte eine Klasse, die mit meinem Backend spricht, Server. Es wurde größer, um zwei verschiedene Ziel-Apps abzudecken. Manche Leute mögen eine große Datei, teilen sich aber logisch die Erweiterungen auf. Meine Präferenz ist es, jede Datei relativ kurz zu halten, deshalb habe ich die folgende Lösung gewählt. Server entsprach ursprünglich CloudAdapterProtocol und implementierte alle Methoden. Was ich tat, war, das Protokoll in eine Hierarchie zu verwandeln, indem ich es auf untergeordnete Protokolle verweisen ließ:

protocol CloudAdapterProtocol: ReggyCloudProtocol, ProReggyCloudProtocol {
    var server: CloudServer {
        get set
    }
    func getServerApiVersion(handler: @escaping (String?, Error?) -> Swift.Void)
}

In Server.Swift habe ich

import Foundation
import UIKit
import Alamofire
import AlamofireImage

class Server: CloudAdapterProtocol {
.
.
func getServerApiVersion(handler: @escaping (String?, Error?) -> Swift.Void) {
.
.
}

Server.Swift implementiert dann nur die Core Server-API zum Festlegen des Servers und zum Abrufen der API-Version. Die eigentliche Arbeit ist in zwei Dateien aufgeteilt:

Server_ReggyCloudProtocol.Swift
Server_ProReggyCloudProtocol.Swift

Diese implementieren die jeweiligen Protokolle.

Es bedeutet, dass Sie Importdeklarationen in den anderen Dateien haben müssen (in diesem Beispiel für Alamofire), aber es ist eine saubere Lösung in Bezug auf die Trennung der Schnittstellen aus meiner Sicht.

Ich denke, dass dieser Ansatz bei extern festgelegten Klassen genauso gut funktioniert wie bei Ihren eigenen.

0
Faisal Memon