Какова наилучшая практика для именования файлов 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, какой должен быть вызван быстрый файл-источник?

Ответ 1

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

String+UTF8Data.swift

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

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

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

Ответ 2

Нет соглашения о быстрой встрече. Держите это просто:

StringExtensions.swift

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

Ответ 3

Мое предпочтение заключается в том, чтобы поставить "Extension_" в начале файла. (Я поместил все связанные расширения в один и тот же файл.)

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

Итак, расширение, связанное со строкой, должно войти в Extension_String.swift

Ответ 4

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

У меня был класс, который говорил с моим back-end, называемым 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 в этом примере), но это чистое решение с точки зрения разделения интерфейсов на мой взгляд.

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

Ответ 5

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

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