Es posible agregar extensiones a los tipos de objetos Swift existentes usando extensiones, como se describe en la especificación del lenguaje .
Como resultado, es posible crear extensiones como:
extension String {
var utf8data:NSData {
return self.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
}
}
Sin embargo, ¿cuál es la mejor práctica de nomenclatura para los archivos fuente de Swift que contienen tales extensiones?
En el pasado, la convención era usar extendedtype+categoryname.m
para el tipo Objective-C como se discutió en la guía Objective-C . Pero el ejemplo de Swift no tiene un nombre de categoría, y llamarlo String.swift
no parece apropiado.
Entonces la pregunta es: dada la String
extensión anterior , ¿cómo debe llamarse el archivo fuente rápido?
ios
objective-c
swift
xcode
AlBlue
fuente
fuente
ClassName+ExtensionName
formato, y que no veo que mucha gente siga usando. Además, me parece torpe en lugar de solo definir clases y extensiones juntas, o darle al archivo un nombre mejorFooAbleTypes
y definir instancias en conjunto.Extensions.swift
. De esa manera, no los perderá de vista y los recién llegados a la base de código los notarán de inmediato. Y preferiría mantener las extensiones únicas privadas para el archivo en el que se necesitan.Respuestas:
La mayoría de los ejemplos que he visto imitan el enfoque de Objective-C. La extensión de ejemplo anterior sería:
String+UTF8Data.swift
Las ventajas son que la convención de nomenclatura facilita la comprensión de que es una extensión y qué clase se está extendiendo.
El problema con el uso
Extensions.swift
o inclusoStringExtensions.swift
es que no es posible inferir el propósito del archivo por su nombre sin mirar su contenido.Usar el
xxxable.swift
enfoque utilizado por Java funciona bien para protocolos o extensiones que solo definen métodos. Pero, de nuevo, el ejemplo anterior define un atributo para queUTF8Dataable.swift
no tenga mucho sentido gramatical.fuente
ExtendedType+Functionality.swift
, ¿es una buena práctica clasificar todas lasString
extensiones, por ejemplo, en su propia subcarpeta (es decir,String
oString Extensions
) en laExtensions
carpeta? ¿O es mejor simplemente almacenar todos los archivos de extensión en el mismo nivel en laExtensions
carpeta?No hay una convención rápida. Mantenlo simple:
Creo un archivo para cada clase que estoy ampliando. Si usa un solo archivo para todas las extensiones, rápidamente se convertirá en una jungla.
fuente
Prefiero
StringExtensions.swift
hasta que agregué demasiadas cosas para dividir el archivo en algo comoString+utf8Data.swift
yString+Encrypt.swift
.Una cosa más, combinar archivos similares en uno hará que su edificio sea más rápido. Consulte Optimización-Swift-Build-Times
fuente
Si tiene un conjunto de mejoras comunes y diversas acordadas por el equipo, agruparlas como Extensions.swift funciona como una solución de primer nivel Keep-It-Simple. Sin embargo, a medida que crece su complejidad, o las extensiones se involucran más, se necesita una jerarquía para encapsular la complejidad. En tales circunstancias, recomiendo la siguiente práctica con un ejemplo.
Tuve una clase que habla con mi back-end, llamada
Server
. Comenzó a crecer para cubrir dos aplicaciones de destino diferentes. A algunas personas les gusta un archivo grande pero simplemente se dividen lógicamente con extensiones. Mi preferencia es mantener cada archivo relativamente corto, así que elegí la siguiente solución.Server
originalmente conformadoCloudAdapterProtocol
e implementado todos sus métodos. Lo que hice fue convertir el protocolo en una jerarquía, haciendo que se refiriera a protocolos subordinados:En
Server.swift
tengoServer.swift
luego solo implementa la API del servidor central para configurar el servidor y obtener la versión de la API. El verdadero trabajo se divide en dos archivos:Estos implementan los protocolos respectivos.
Significa que necesita tener declaraciones de importación en los otros archivos (para Alamofire en este ejemplo) pero es una solución limpia en términos de segregación de interfaces en mi opinión.
Creo que este enfoque funciona igualmente bien con clases especificadas externamente y con la suya propia.
fuente
¿Por qué es esto incluso un debate? ¿Debo poner todas mis subclases en un archivo llamado _Subclasses.swift? Yo creo que no. Swift tiene espaciado de nombre basado en módulo. Para extender una clase Swift bien conocida necesita un archivo que sea específico para su propósito. Podría tener un equipo grande que cree un archivo que sea UIViewExtensions.swift que no exprese ningún propósito y confunda a los desarrolladores y podría duplicarse fácilmente en el proyecto que no se construiría. La convención de nomenclatura Objective-C funciona bien y hasta que Swift tenga un espaciado de nombre real, es la mejor manera de hacerlo.
fuente
En lugar de agregar mis comentarios por todas partes, los estoy exponiendo a todos aquí en una respuesta.
Personalmente, adopto un enfoque híbrido que brinda buena usabilidad y claridad, al mismo tiempo que no abarrota el área de superficie API para el objeto que estoy extendiendo.
Por ejemplo, cualquier cosa que tenga sentido para estar disponible para cualquier cadena iría
StringExtensions.swift
comotrimRight()
yremoveBlankLines()
.Sin embargo, si tuviera una función de extensión, como
formatAsAccountNumber()
sería no ir en ese archivo porque 'Número de cuenta' no es algo que naturalmente aplicarse a cualquier / todas las cadenas y sólo tiene sentido en el contexto de las cuentas. En ese caso, crearía un archivo llamadoStrings+AccountFormatting.swift
o tal vez inclusoStrings+CustomFormatting.swift
con unaformatAsAccountNumber()
función si hay varios tipos / formas de formatearlo.En realidad, en ese último ejemplo, disuadí activamente a mi equipo de usar extensiones como esa en primer lugar, y en su lugar alentaría algo como
AccountNumberFormatter.format(String)
eso, ya que eso no toca laString
superficie de la API, como no debería. La excepción sería si definió esa extensión en el mismo archivo donde se usa, pero de todos modos no tendría su propio nombre de archivo.fuente
Prefiero tener un
+
para subrayar el hecho de que contiene extensiones:String+Extensions.swift
Y si el archivo se vuelve demasiado grande, puede dividirlo para cada propósito:
String+UTF8Data.swift
String+Encrypt.swift
fuente