it-swarm.com.ru

Как лучше всего именовать файлы Swift, которые добавляют расширения к существующим объектам?

Можно добавить расширения к существующим типам объектов Swift, используя расширения, как описано в спецификации языка .

В результате возможно создание расширений, таких как:

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

Тем не менее, какова наилучшая практика именования исходных файлов Swift, содержащих такие расширения? 

В прошлом было принято использовать extendedtype+categoryname.m для типа Objective-C , Как обсуждалось в руководстве Objective-C . Но в примере Swift нет названия категории, и называть его String.Swift не представляется целесообразным.

Таким образом, вопрос заключается в следующем: учитывая указанное выше расширение String, как должен называться исходный файл Swift?

125
AlBlue

Большинство примеров, которые я видел, имитируют подход Objective-C. Пример расширения выше будет:

String+UTF8Data.Swift

Преимущества в том, что соглашение об именах позволяет легко понять, что это расширение и какой класс расширяется.

Проблема с использованием Extensions.Swift или даже StringExtensions.Swift заключается в том, что невозможно определить назначение файла по его имени, не глядя на его содержимое.

Использование подхода xxxable.Swift в том виде, в котором он используется в Java, работает нормально для протоколов или расширений, которые определяют только методы. Но опять же, пример выше определяет атрибут, так что UTF8Dataable.Swift не имеет большого грамматического смысла.

149
picciano

Свифта нет. Будь проще:

StringExtensions.Swift

Я создаю один файл для каждого расширяемого класса. Если вы используете один файл для всех расширений, он быстро превратится в джунгли.

5
Mike Taverne

Я предпочитаю ставить «Extension_» в начале файла. (Я поместил все связанные расширения в один файл.)

Таким образом, все файлы расширений находятся в алфавитном порядке в каталоге моего приложения и навигаторе Xcode. Конечно, в навигаторе я тоже могу их сгруппировать.

Таким образом, связанное с String расширение будет входить в Extension_String.Swift

1
leanne

Я предпочитаю StringExtensions.Swift, пока не добавлю слишком много вещей, чтобы разбить файл на что-то вроде String+utf8Data.Swift и String+Encrypt.Swift.

Еще одна вещь, объединение одинаковых файлов в один сделает ваше здание быстрее. Обратитесь к Optimizing-Swift-Build-Times

1
DawnSong

Если у вас есть согласованный командой набор общих и разных улучшений, объедините их вместе как расширения. Работает как решение первого уровня Keep-It-Simple. Однако, по мере того как ваша сложность возрастает или расширения становятся более сложными, для инкапсуляции сложности необходима иерархия. В таких условиях я рекомендую следующую практику с примером.

У меня был класс, который общается с моим бэкэндом, который называется Server. Он начал расти, чтобы охватить два разных целевых приложения. Некоторым людям нравится большой файл, но он логически разделен с расширениями. Я предпочитаю, чтобы каждый файл был относительно коротким, поэтому я выбрал следующее решение. Изначально Server соответствовал CloudAdapterProtocol и реализовал все его методы. Что я сделал, так это превратил протокол в иерархию, сделав ссылку на подчиненные протоколы:

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

В Server.Swift у меня есть

import Foundation
import UIKit
import Alamofire
import AlamofireImage

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

Затем Server.Swift просто реализует API главного сервера для настройки сервера и получения версии API. Настоящая работа разбита на два файла:

Server_ReggyCloudProtocol.Swift
Server_ProReggyCloudProtocol.Swift

Они реализуют соответствующие протоколы.

Это означает, что вам нужно иметь объявления импорта в других файлах (для Alamofire в этом примере), но это чистое решение с точки зрения разделения интерфейсов, на мой взгляд.

Я думаю, что этот подход одинаково хорошо работает как с внешними классами, так и с вашими.

0
Faisal Memon