Il est possible d'ajouter des extensions aux types d'objets Swift existants à l'aide d'extensions, comme décrit dans la spécification du 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?
Dans le passé, la convention était d'utiliser extendedtype+categoryname.m
pour le type Objective-C comme indiqué dans le guide Objective-C . Mais l'exemple Swift n'a pas de nom de catégorie et l'appeler String.swift
ne semble pas approprié.
La question est donc: étant donné l' String
extension ci-dessus , comment le fichier source swift doit-il être appelé?
ios
objective-c
swift
xcode
AlBlue
la source
la source
ClassName+ExtensionName
format, et que je ne vois pas encore trop de gens utiliser. En outre, je trouve cela maladroit au lieu de simplement définir des classes et des extensions ensemble, ou de donner au fichier un meilleur nom commeFooAbleTypes
et de définir des instances dans l'agrégat.Extensions.swift
. De cette façon, vous ne les perdrez pas de vue et les nouveaux arrivants dans la base de code les remarqueront immédiatement. Et je préfère garder les extensions ponctuelles privées pour le fichier dans lequel elles ont besoin.Réponses:
La plupart des exemples que j'ai vus imitent l'approche Objective-C. L'exemple d'extension ci-dessus serait:
String+UTF8Data.swift
Les avantages sont que la convention de dénomination permet de comprendre facilement qu'il s'agit d'une extension et quelle classe est étendue.
Le problème avec l'utilisation
Extensions.swift
ou mêmeStringExtensions.swift
est qu'il n'est pas possible de déduire le but du fichier par son nom sans regarder son contenu.L'utilisation de l'
xxxable.swift
approche 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 donc celaUTF8Dataable.swift
n'a pas beaucoup de sens grammatical.la source
ExtendedType+Functionality.swift
, est-il recommandé de trier toutes lesString
extensions, par exemple, dans leur propre sous-dossier (c'estString
-à- dire ouString Extensions
) sous leExtensions
dossier? Ou est-il préférable de simplement stocker tous les fichiers d'extension au même niveau sous leExtensions
dossier?Il n'y a pas de convention Swift. Rester simple:
Je crée un fichier pour chaque classe que j'étends. Si vous utilisez un seul fichier pour toutes les extensions, il deviendra rapidement une jungle.
la source
Je préfère
StringExtensions.swift
jusqu'à ce que j'aie ajouté trop de choses pour diviser le fichier en quelque chose commeString+utf8Data.swift
etString+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
la source
Si vous avez un ensemble d'améliorations communes et diverses approuvées par l'équipe, les regrouper sous la forme d'une extension.swift fonctionne comme une solution de premier niveau Keep-It-Simple. Cependant, à mesure que votre complexité augmente ou que les extensions deviennent plus impliquées, 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 parle à mon back-end, appelé
Server
. Il a commencé à s'agrandir pour couvrir deux applications cibles différentes. Certaines personnes aiment un gros fichier 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
à l'origine conformeCloudAdapterProtocol
et implémenté toutes ses méthodes. Ce que j'ai fait, c'est transformer le protocole en hiérarchie, en le faisant référence à des protocoles subordonnés:Dans
Server.swift
j'aiServer.swift
puis implémente 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:Ceux-ci mettent en œuvre 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 en externe que les vôtres.
la source
Pourquoi est-ce même un débat? Dois-je mettre toutes mes sous-classes dans un fichier appelé _Subclasses.swift. Je crois que non. Swift a un espacement des noms basé sur les modules. Pour étendre une classe Swift bien connue, il faut un fichier spécifique à son objectif. Je pourrais avoir une grande équipe qui crée un fichier qui est UIViewExtensions.swift qui n'exprime aucun but et qui confondra les développeurs et pourrait être facilement dupliqué dans le projet qui ne serait pas construit. La convention de dénomination Objective-C fonctionne bien et jusqu'à ce que Swift ait un espacement réel des noms, c'est la meilleure solution.
la source
Plutôt que d'ajouter mes commentaires partout, je les expose tous ici en une seule réponse.
Personnellement, j'adopte une approche hybride qui donne à la fois une bonne convivialité et une bonne clarté, tout en n'encombrant pas la surface API de l'objet que j'étends.
Par exemple, tout ce qui a du sens pour être disponible pour n'importe quelle chaîne irait dans
StringExtensions.swift
tel quetrimRight()
etremoveBlankLines()
.Cependant, si j'avais une fonction d'extension telle
formatAsAccountNumber()
qu'elle n'entrerait pas dans ce fichier, car le `` numéro de compte '' n'est pas quelque chose qui s'appliquerait naturellement à toutes les chaînes et n'a de sens que dans le contexte des comptes. Dans ce cas, je créerais un fichier appeléStrings+AccountFormatting.swift
ou peut-être mêmeStrings+CustomFormatting.swift
avec uneformatAsAccountNumber()
fonction s'il existe plusieurs types / façons de le formater.En fait, dans ce dernier exemple, je dissuade activement mon équipe d'utiliser des extensions comme celle-là en premier lieu, et j'encouragerais plutôt quelque chose comme à la
AccountNumberFormatter.format(String)
place car cela ne touche pas du tout laString
surface de l' API, comme cela ne devrait pas. L'exception serait si vous définissiez cette extension dans le même fichier où elle est utilisée, mais alors elle n'aurait pas son propre nom de fichier de toute façon.la source
Je préfère avoir un
+
pour souligner le fait qu'il contient des extensions:String+Extensions.swift
Et si le fichier devient trop volumineux, vous pouvez le diviser pour chaque objectif:
String+UTF8Data.swift
String+Encrypt.swift
la source