Les extensions en Swift sont apparues comme un moyen d'étendre les types — tant standards (par exemple, String, Array) que personnalisés, sans avoir besoin de créer des sous-classes ou de modifier le code source original. Cela permet d'ajouter de nouvelles méthodes, des propriétés calculées, des conformités aux protocoles et même une conformité à des protocoles, tout en préservant la lisibilité et une architecture de code uniforme.
Problème survient avec un usage excessif ou désordonné des extensions : il est facile de perdre le contrôle sur le comportement d'origine des types, des conflits de noms peuvent survenir, et il devient plus difficile de suivre l'origine des éléments, en particulier dans de grands projets ou lors de l'intégration de bibliothèques tierces.
Solution consiste en une structure claire, l'organisation des extensions par groupes de sens, une documentation explicite et l'évitement des conflits avec les noms existants, ainsi qu'une limitation, si nécessaire, du champ d'application (par exemple, via fileprivate ou internal).
Exemple de code :
extension String { var isEmail: Bool { return self.contains("@") && self.contains(".") } func trimmed() -> String { return trimmingCharacters(in: .whitespacesAndNewlines) } }
Points clés :
Peut-on ajouter une propriété stockée via une extension ?
Non, une extension permet d'ajouter uniquement des propriétés calculées et des méthodes. Les propriétés stockées ne peuvent pas être ajoutées via une extension. Essayez — le compilateur générera immédiatement une erreur.
Que se passe-t-il si deux extensions différentes déclarent des méthodes avec les mêmes noms pour un même type dans des fichiers différents ?
Il y aura un conflit de noms, Swift ne pourra pas décider quelle méthode appeler, et l'erreur apparaîtra lors de la compilation.
Les extensions peuvent-elles implémenter des méthodes privées, visibles uniquement à l'intérieur de l'extension ?
Oui, si on déclare une méthode avec le mot-clé private, elle ne sera visible qu'à l'intérieur de l'extension elle-même et du fichier dans lequel elle est déclarée (si on utilise fileprivate).
extension Int { private func isEvenInternal() -> Bool { return self % 2 == 0 } func publicCheckEven() -> Bool { return isEvenInternal() } }
** Cas négatif **
Dans un grand projet, des méthodes sont ajoutées à String via des extensions pour tout — de la validation d'email à l'analyse de JSON. Au bout d'un an, personne ne peut comprendre d'où viennent les éléments : les méthodes se chevauchent par leurs noms, quelqu'un ajoute une nouvelle fonction sans connaître l'ancienne, et perturbe le comportement des dépendances.
Avantages :
Inconvénients :
** Cas positif **
L'équipe utilise des extensions pour des groupes logiques : une extension distincte pour la validation, une autre pour le formatage, avec des aides privées à l'intérieur. Toutes les méthodes sont documentées, l'utilisation de nouvelles méthodes est discutée, et il y a une revue de code.
Avantages :
Inconvénients :