web-dev-qa-db-fra.com

Quelle est la meilleure pratique pour nommer les fichiers Swift qui ajoutent des extensions aux objets existants?

Il est possible d'ajouter des extensions aux types d'objet Swift existants à l'aide d'extensions, comme décrit dans la spécification de langage .

En conséquence, il est possible de créer des extensions telles que:

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

Cependant, quelle est la meilleure pratique de dénomination pour les fichiers source Swift contenant de telles extensions? 

Auparavant, la convention consistait à utiliser extendedtype+categoryname.m pour le type Objective-C Comme indiqué dans le guide Objective-C . Mais l'exemple de Swift n'a pas de nom de catégorie et l'appel de String.Swift ne semble pas approprié.

La question est donc: étant donné l'extension String ci-dessus, comment le fichier source Swift doit-il être appelé?

125
AlBlue

La plupart des exemples que j'ai vus imitent l'approche Objective-C. L'extension d'exemple ci-dessus serait:

String+UTF8Data.Swift

L'avantage est que la convention de dénomination permet de comprendre facilement qu'il s'agit d'une extension et de la classe en cours d'extension.

Le problème avec Extensions.Swift ou même StringExtensions.Swift est qu’il n’est pas possible de déduire l’objet du fichier par son nom sans regarder son contenu.

Utiliser l'approche xxxable.Swift utilisée par Java fonctionne bien pour les protocoles ou les extensions qui ne définissent que des méthodes. Mais encore une fois, l’exemple ci-dessus définit un attribut de sorte que UTF8Dataable.Swift n’a pas beaucoup de sens grammatical.

149
picciano

Il n'y a pas de convention Swift. Rester simple:

StringExtensions.Swift

Je crée un fichier pour chaque classe que je développe. Si vous utilisez un seul fichier pour toutes les extensions, il deviendra rapidement une jungle.

5
Mike Taverne

Ma préférence est de mettre "Extension_" au début du fichier. (Je mets toutes les extensions associées dans le même fichier.)

Ainsi, tous les fichiers d’extension sont regroupés, par ordre alphabétique, dans le répertoire de mon application et dans le navigateur de Xcode. Bien sûr, dans le navigateur, je peux aussi les regrouper.

Ainsi, une extension liée à la chaîne irait dans Extension_String.Swift

1
leanne

Je préfère StringExtensions.Swift jusqu'à ce que j'ajoute trop d'éléments pour diviser le fichier en quelque chose comme String+utf8Data.Swift et String+Encrypt.Swift.

Une dernière chose, combiner des fichiers similaires en un seul rendra votre bâtiment plus rapide. Reportez-vous à Optimizing-Swift-Build-Times

1
DawnSong

Si vous disposez d'un ensemble d'améliorations communes et diverses convenues par l'équipe, regroupez-les en tant qu'extensions. Swift fonctionne en tant que solution Keep-It-Simple de premier niveau. Cependant, au fur et à mesure que votre complexité augmente ou que les extensions deviennent plus complexes, une hiérarchie est nécessaire pour encapsuler la complexité. Dans de telles circonstances, je recommande la pratique suivante avec un exemple.

J'ai eu un cours qui s'adresse à mon serveur, appelé Server. Il a commencé à grossir pour couvrir deux applications cibles différentes. Certaines personnes aiment les gros fichiers mais se séparent logiquement avec des extensions. Ma préférence est de garder chaque fichier relativement court, j'ai donc choisi la solution suivante. Server était à l'origine conforme à CloudAdapterProtocol et implémentait toutes ses méthodes. Ce que j'ai fait était de transformer le protocole en une hiérarchie, en le faisant référence à des protocoles subordonnés:

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

Dans Server.Swift j'ai

import Foundation
import UIKit
import Alamofire
import AlamofireImage

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

Server.Swift implémente alors simplement l'API du serveur principal pour configurer le serveur et obtenir la version de l'API. Le vrai travail est divisé en deux fichiers:

Server_ReggyCloudProtocol.Swift
Server_ProReggyCloudProtocol.Swift

Ceux-ci implémentent les protocoles respectifs.

Cela signifie que vous devez avoir des déclarations d'importation dans les autres fichiers (pour Alamofire dans cet exemple), mais c'est une solution propre en termes de séparation des interfaces à mon avis.

Je pense que cette approche fonctionne aussi bien avec les classes spécifiées de l'extérieur que les vôtres.

0
Faisal Memon