É possível adicionar extensões aos tipos de objetos Swift existentes usando extensões, conforme descrito na especificação do idioma .
Como resultado, é possível criar extensões como:
extension String {
var utf8data:NSData {
return self.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
}
}
No entanto, qual é a melhor prática de nomeação para arquivos de origem Swift que contêm essas extensões?
No passado, a convenção era extendedtype+categoryname.m
para o tipo Objective-C, conforme discutido no guia Objective-C . Mas o exemplo Swift não tem um nome de categoria, e chamá-lo String.swift
não parece apropriado.
Portanto, a pergunta é: dada a String
extensão acima , como deve ser chamado o arquivo de origem rápido?
ios
objective-c
swift
xcode
AlBlue
fonte
fonte
ClassName+ExtensionName
formato e que não vejo muitas pessoas ainda usando. Além disso, acho isso desajeitado em vez de apenas definir classes e extensões em conjunto, ou dar ao arquivo um nome melhorFooAbleTypes
e definir instâncias de forma agregada.Extensions.swift
. Dessa forma, você não os perderá e os recém-chegados à base de código os notarão imediatamente. E eu preferiria manter one-off extensões privadas para o arquivo eles são necessários no.Respostas:
A maioria dos exemplos que vi imitam a abordagem Objective-C. A extensão de exemplo acima seria:
String+UTF8Data.swift
As vantagens são que a convenção de nomenclatura facilita a compreensão de que é uma extensão e qual classe está sendo estendida.
O problema com o uso
Extensions.swift
ou mesmoStringExtensions.swift
é que não é possível inferir a finalidade do arquivo pelo nome sem examinar o conteúdo.Usar a
xxxable.swift
abordagem usada pelo Java funciona bem para protocolos ou extensões que definem apenas métodos. Mas, novamente, o exemplo acima define um atributo para queUTF8Dataable.swift
não faça muito sentido gramatical.fonte
ExtendedType+Functionality.swift
, é uma boa prática classificar todas asString
extensões, por exemplo, em sua própria subpasta (String
ou sejaString Extensions
) naExtensions
pasta? Ou é melhor apenas armazenar todos os arquivos de extensão no mesmo nível naExtensions
pasta?Não existe uma convenção Swift. Mantenha simples:
Eu crio um arquivo para cada classe que estou estendendo. Se você usar um único arquivo para todas as extensões, ele rapidamente se tornará uma selva.
fonte
Eu prefiro
StringExtensions.swift
até adicionar coisas demais para dividir o arquivo em algo comoString+utf8Data.swift
eString+Encrypt.swift
.Mais uma coisa, combinar arquivos semelhantes em um só tornará sua construção mais rápida. Consulte Optimizing-Swift-Build-Times
fonte
Se você tiver um conjunto acordado em equipe de aprimoramentos comuns e diversos, agrupá-los como um Extensions.swift funcionará como uma solução de primeiro nível de Manutenção simples. No entanto, à medida que sua complexidade aumenta ou as extensões se tornam mais envolvidas, é necessária uma hierarquia para encapsular a complexidade. Em tais circunstâncias, recomendo a prática a seguir com um exemplo.
Eu tive uma aula que fala com meu back-end, chamada
Server
. Começou a crescer para cobrir dois aplicativos de destino diferentes. Algumas pessoas gostam de um arquivo grande, mas apenas se separam logicamente com extensões. Minha preferência é manter cada arquivo relativamente curto, então escolhi a seguinte solução.Server
originalmente conformeCloudAdapterProtocol
e implementou todos os seus métodos. O que fiz foi transformar o protocolo em uma hierarquia, fazendo-o se referir a protocolos subordinados:Em
Server.swift
que tenhoServer.swift
então apenas implementa a API do servidor núcleo para configurar o servidor e obter a versão da API. O trabalho real é dividido em dois arquivos:Eles implementam os respectivos protocolos.
Isso significa que você precisa ter declarações de importação nos outros arquivos (para Alamofire neste exemplo), mas é uma solução limpa em termos de segregação de interfaces na minha opinião.
Eu acho que essa abordagem funciona igualmente bem com classes especificadas externamente e com as suas próprias.
fonte
Por que isso é mesmo um debate? Devo colocar todas as minhas subclasses em um arquivo chamado _Subclasses.swift. Eu acho que não. Swift possui espaçamento de nome baseado em módulo. Para estender uma classe Swift conhecida, é necessário um arquivo específico para sua finalidade. Eu poderia ter uma grande equipe que cria um arquivo que é o UIViewExtensions.swift que não tem propósito algum e confunde os desenvolvedores e pode ser facilmente duplicado no projeto que não seria criado. A convenção de nomenclatura Objective-C funciona bem e até Swift ter espaçamento de nome real, é o melhor caminho a percorrer.
fonte
Em vez de adicionar meus comentários em todo o lugar, eu os estou colocando aqui em uma resposta.
Pessoalmente, adoto uma abordagem híbrida que oferece boa usabilidade e clareza, além de não sobrecarregar a área de superfície da API para o objeto que estou estendendo.
Por exemplo, qualquer coisa que faça sentido estar disponível para qualquer string seria
StringExtensions.swift
comotrimRight()
eremoveBlankLines()
.No entanto, se eu tivesse uma função de extensão, como
formatAsAccountNumber()
ela não entraria nesse arquivo, porque 'Número da conta' não é algo que se aplicaria naturalmente a todas / todas as strings e só faz sentido no contexto das contas. Nesse caso, eu criaria um arquivo chamadoStrings+AccountFormatting.swift
ou talvezStrings+CustomFormatting.swift
com umaformatAsAccountNumber()
função se houver vários tipos / maneiras de realmente formatá-lo.Na verdade, nesse último exemplo, eu dissuito ativamente minha equipe de usar extensões como essa em primeiro lugar e, em vez disso, incentivaria algo como
AccountNumberFormatter.format(String)
isso, pois isso não afeta aString
área da superfície da API, como deveria. A exceção seria se você definisse essa extensão no mesmo arquivo em que é usada, mas não teria seu próprio nome de arquivo.fonte
Prefiro
+
sublinhar o fato de que ele contém extensões:String+Extensions.swift
E se o arquivo ficar muito grande, você poderá dividi-lo para cada finalidade:
String+UTF8Data.swift
String+Encrypt.swift
fonte