Mevcut nesnelere uzantı ekleyen Swift dosyalarını adlandırmak için en iyi yöntem nedir?


166

Dil belirtiminde açıklandığı gibi, uzantıları kullanarak mevcut Swift nesne türlerine uzantılar eklemek mümkündür .

Sonuç olarak, aşağıdakiler gibi uzantılar oluşturmak mümkündür:

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

Ancak, bu tür uzantıları içeren Swift kaynak dosyaları için en iyi adlandırma uygulaması nedir?

Geçmişte, kural Objective-C kılavuzundaextendedtype+categoryname.m tartışıldığı gibi Objective-C tipi için kullanmaktı . Ancak Swift örneğinin kategori adı yok ve onu çağırmak uygun görünmüyor.String.swift

Yani soru şudur: yukarıdaki Stringuzantı göz önüne alındığında , hızlı kaynak dosyaya ne denir?


5
Bu bir kod sorusu soru değil - Bu belirli örnek umurumda değil, hızlı adlandırma kuralının ne olduğunu bilmek istiyorum.
AlBlue

2
Adlandırma kuralı yoktur. Devam etmemiz gereken tek şey, her zaman ClassName+ExtensionNameformatı takip eden ve hala çok fazla insanın görmediğini gördüğüm Objective-C kategorileri . Ayrıca, sadece sınıfları ve uzantıları birlikte tanımlamak yerine veya dosyaya FooAbleTypestoplu olarak örnekleri daha iyi bir ad vermek ve tanımlamak yerine bu kadar karmaşık buluyorum .
CodaFi

4
Henüz bir adlandırma uygulaması yok. İşte bir düşünce: tüm global uzantıları tek bir yerde toplayın Extensions.swift. Bu şekilde, bunların izini kaybetmezsiniz ve kod tabanına yeni gelenler hemen fark eder. Ve bir kerelik uzantıları ihtiyaç duydukları dosyaya özel tutmayı tercih ederim.
Andrew

1
Andrew'un dediği gibi, henüz standart bir adlandırma uygulaması yok - bu nedenle yeni oluşturulmuş bir topluluğun önerilen bazı fikirlere gelebilmesi için bu sorudan özellikle fikir alması istendi.
AlBlue

1
Bence tek bir extensions.swift dosyası. İhtiyacınız olanı kolayca bulmak için içindeki yapıyı düzenli bir şekilde (kendi tarzınızda) tutun. Tek bir dosyayı kopyalamak veya çeşitli projelerden bağlantı oluşturmak kolaydır ve bir şeyleri unutmayın.
Yohst

Yanıtlar:


202

Gördüğüm örneklerin çoğu Objective-C yaklaşımını taklit ediyor. Yukarıdaki örnek uzantı şu şekildedir:

String+UTF8Data.swift

Avantajları, adlandırma kuralının bir uzantı olduğunu ve hangi Sınıfın genişletildiğini anlamayı kolaylaştırmasıdır.

Kullanmayla ilgili Extensions.swiftveya hatta sorun StringExtensions.swift, içeriğine bakmadan dosyanın amacını adıyla çıkarmanın mümkün olmamasıdır.

xxxable.swiftJava tarafından kullanılan yaklaşımı kullanmak , yalnızca yöntemleri tanımlayan protokoller veya uzantılar için uygundur. Fakat yine, yukarıdaki örnek, UTF8Dataable.swiftçok fazla gramer anlamsız bir özellik tanımlar .


2
Adlandırma kuralı ile genişletilen şeyi çıkarsa da, IHMO gereksiz bir komplikasyondur. Tonlarca <name> + <extention> .swift dosyası yerine, genellikle her proje için kullandığım tek bir extensions.swift dosyası tutuyorum. Dosya dahili olarak, genişletilmiş belirli bir sınıfı bulmak kolay olacak şekilde düzenlenmiştir.
Yohst

18
Bu cevap, <name> + <extention> .swift, Xcode 8'de Temel Veriler için NSManagedObject alt sınıfları oluştururken Xcode'un bunu gerçekleştirme şeklidir. Örnek: Foo + CoreDataProperties.swift.
Jerry Krinock

5
Uzantı birden çok yöntem uygularsa ne olur?
AlexVPerl

2
Sadece olabildiğince açıklayıcı olun. Örneğin, Görüntü'ye filtre uygulamak için farklı işlevler içeren bir uzantınız varsa, buna Görüntü + Filtreler.swift adını verin. Genişletilmiş işlevlerde ilgili gruplar için farklı dosyalar kullanmak iyidir. İlişkili şeyleri birlikte gruplayın, ancak ilgisiz şeyleri ayrı tutun. Hayat güzel olacak.
picciano

Kuralını kullanıyorsanız, ExtendedType+Functionality.swifttüm Stringuzantıları, örneğin, klasör altındaki kendi alt klasörlerine (yani Stringveya String Extensions) ayırmak iyi bir uygulama Extensionsmudur? Yoksa tüm uzantı dosyalarını Extensionsklasör altında aynı düzeyde saklamak daha mı iyi ?
Noah Wilder

9

Swift sözleşmesi yoktur. Basit tutun:

StringExtensions.swift

Genişlettiğim her sınıf için bir dosya oluşturuyorum. Tüm uzantılar için tek bir dosya kullanırsanız, hızlı bir şekilde orman olur.


8
Bu özellikle yeniden kullanılabilir görünmüyor.
Keller

1
İle karşılaştırıldığında?
Mike Taverne

3
Tek (veya açıkça ilişkilendirilebilir) bir amaca hizmet eden tek bir (veya sıkıca bağlı) sınıf uzantıları dosyasıyla karşılaştırıldığında. "StringExtensions" gibi bir şey, genel amaçlı Dize dezenfeksiyonundan uygulamaya özgü mantığa kadar her şeyi içerebileceğine benziyor. Yeniden kullanım endişe ediyorsa en iyi yaklaşım olmayabilir. Kakao adlandırma kuralı uygulama yerine işleve doğru eğilir. Ben "StringExtensions" ikincisini gösterir iddia. Konvansiyonu bir yana, kabul edilen cevabı kesinlikle ObjC'de tercih ediyorum, ancak Swift'te modüller nedeniyle daha iyi bir yaklaşım gibi görünüyor.
Keller

2
Mantıklı. Yeniden kullanımın bir endişe olmadığı tek bir uygulamayı düşünüyordum. Örneğin, uzantı olarak kullanmak istediğim birkaç ilişkisiz dize işlevim olduğunu varsayalım - bir dosya oluşturabilir ve tüm bu işlevleri oraya koyabilir veya işlev başına bir dosya oluşturabilirim. Bu durumda tek bir dosyanın basitliğini seviyorum. Ama mantığınız sağlam. Teşekkürler.
Mike Taverne

Burada eklenenlerin doğal olarak tüm dizeler için geçerli olması şartıyla (örn. 'TrimRight ()') bu mantıklıdır. Daha fazla kullanım-duruma özgü bir şeyse (yani 'formatAccountNumber ()'), dosya 'Strings + AccountFormatting.swift' olmalı ve yalnızca gerçekte, Başka bir yerde 'Dizeler' yüzey API'sı.
Mark A. Donohoe

1

Tercihim StringExtensions.swiftben gibi bir şey dosyayı bölmek için çok fazla şeyler katma kadar String+utf8Data.swiftve String+Encrypt.swift.

Bir şey daha, benzer dosyaları bir araya getirmek binanızı daha hızlı hale getirecektir. Bakınız Optimize-Swift-Yap-Times


1
Aynı şey için iki dosya adlandırma kuralı vardır. Bence bu kötü.
anlam önemlidir

@ anlamı önemlidir. İki adlandırma kuralı, Apple Documents tarafından iyi bilinir ve önerilir. İstediğin gibi yap.
DawnSong

Ben daha fazla programcı adlandırma ve kod [formatlama] varyasyonlarını sınırlayarak zarafet için çaba isterdim.
anlam önemlidir

@ Anlam önemlidir Elegance'ın iki tarafı vardır, C benzeri dillerde kıvırcık parantezlerin nasıl yazıldığına dair klasik tartışmalı bir sorun gibidir. Bu önemsiz, bu yüzden çoğu insan bunu kabul edene kadar birini seçip zorunlu hale getirmenin gerekli olduğunu düşünmüyorum.
DawnSong

Tutarlılığın zarafetini kastetmiştim: uzantıları adlandırmanın bir yolunu veya kıvırcık parantezleri yerleştirmenin bir yolunu kullanmak. Sonra farklı kıvırcık ayraç stillerinin okunabilirliğinde ölçülebilir bir fark olduğunu düşünüyorum; bu yüzden 'önemsiz' olduğunu düşünmüyorum.
anlam önemlidir

0

Takım tarafından kabul edilen bir dizi ortak ve çeşitli geliştirmeler varsa, bunları bir Uzantılar olarak bir araya getirmek. Swift, Keep-It-Simple birinci düzey çözüm olarak çalışır. Bununla birlikte, karmaşıklığınız büyüdükçe veya uzantılar daha karmaşık hale geldiğinde, karmaşıklığı kapsüllemek için bir hiyerarşi gerekir. Bu gibi durumlarda aşağıdaki uygulamayı bir örnekle öneririm.

Arka uçla konuşan bir sınıfım vardı, denir Server. İki farklı hedef uygulamayı kapsayacak şekilde büyümeye başladı. Bazı insanlar büyük bir dosyayı sever, ancak mantıksal olarak uzantılarla bölünür. Benim tercihim her dosyayı nispeten kısa tutmak, bu yüzden aşağıdaki çözümü seçtim. Serverbaşlangıçta CloudAdapterProtocoltüm yöntemlerine uygun ve uygulanmıştır. Yaptığım protokolü, bağımlı protokollere gönderme yaparak bir hiyerarşiye dönüştürmekti:

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

In Server.swiftBen

import Foundation
import UIKit
import Alamofire
import AlamofireImage

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

Server.swiftsonra sunucuyu ayarlamak ve API sürümünü almak için temel sunucu API'sini uygular. Gerçek çalışma iki dosyaya bölünmüştür:

Server_ReggyCloudProtocol.swift
Server_ProReggyCloudProtocol.swift

Bunlar ilgili protokolleri uygular.

Bu, diğer dosyalarda (bu örnekte Alamofire için) ithalat bildirimlerine sahip olmanız gerektiği anlamına geliyor, ancak bence arayüzleri ayırmak açısından temiz bir çözüm.

Bence bu yaklaşım dışsal olarak belirlenmiş sınıfların yanı sıra kendi sınıflarınızla da eşit derecede iyi çalışır.


0

Bu neden bir tartışma konusu? Tüm alt sınıflarımı _Subclasses.swift adlı bir dosyaya koymalı mıyım? Bence değil. Swift, modül tabanlı ad aralığına sahiptir. İyi bilinen bir Swift sınıfını genişletmek için amacına özgü bir dosyaya ihtiyaç vardır. UIViewExtensions.swift olan, hiçbir amacı ifade etmeyen ve geliştiricileri şaşırtacak ve inşa edilmeyecek projede kolayca çoğaltılabilecek bir dosya oluşturan büyük bir ekibim olabilir. Objective-C adlandırma kuralı iyi çalışır ve Swift gerçek ad aralığına sahip olana kadar gitmek için en iyi yoldur.


Benim durumumda, bu dosyada tanımlanan uzantıların 'placeIn (UIView)' yöntemi gibi herhangi bir / tüm UIView sınıfları için anlamlı olması koşuluyla UIViewExtensions.swift adlı bir dosyaya sahip olmanın mükemmel bir mantıklı olduğunu düşünüyorum. Kullanıma özgü ise (yani, uygulamanın yalnızca bir kısmı için, özel görünüm dekorasyonunu söyleyin, o zaman UIView + CustomDecoration.swift.) UIViewExtensions adlı bir dosyayı söyleme gibi bir genelleme yapmadan önce kullanımı düşünmeniz gerekir. . "hiçbir amaç ifade etmeyen bir değişiklik". amaç tüm UIViews için genel uzantılar olduğunda
Mark A. Donohoe

0

Yerine yorumlarımı eklemek yerine, hepsini burada tek bir cevapta ortaya koyuyorum.

Şahsen, hem iyi kullanılabilirlik hem de netlik sağlayan melez bir yaklaşım benimsiyorum, aynı zamanda genişlettiğim nesne için API yüzey alanını karıştırmıyor.

Örneğin, bu şey markaları anlamda kullanılabilir olması için herhangi içinde gider dize StringExtensions.swiftgibi trimRight()ve removeBlankLines().

Ben gibi bir uzatma fonksiyonu olsaydı Ancak, formatAsAccountNumber()bu olur değil 'Hesap Numarası' doğal olarak herhangi için de geçerli olacak bir şey değildir çünkü dosyada go / tüm dizeleri ve sadece hesaplar bağlamında mantıklı. Bu durumda, aslında biçimlendirmek için çeşitli türler / yollar varsa, Strings+AccountFormatting.swifthatta Strings+CustomFormatting.swiftbir formatAsAccountNumber()işlevle adlandırılan bir dosya oluşturabilirim .

Aslında, bu son örnekte, ekibimi ilk etapta böyle uzantıları kullanmaktan caydırıyorum ve bunun yerine API yüzey alanına AccountNumberFormatter.format(String)hiç dokunmaması gerektiği gibi bir şeyi teşvik ediyorum String. İstisna, aynı uzantıyı kullanıldığı yerde tanımlamış olsaydınız, ancak yine de kendi dosya adına sahip olmazdı.


0

+Uzantıları içeren gerçeğin altını çizmek için bir sahip olmayı tercih ederim :

String+Extensions.swift

Dosya çok büyük olursa, her amaç için bölebilirsiniz:

String+UTF8Data.swift

String+Encrypt.swift

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.