Pull to refresh

Comments 14

Может не надо этого счастья в экосистему ios / mac?
Во-первых, «URL» обладает некоторыми частями, без которых он, как было обозначено в начале, перестает иметь смысл – это scheme и host.

кажется, что это уже ошибка. "/etc/passwd" – нормальный валидный ur

"/etc/passwd" – нормальный валидный ur

Это не так, согласно RFC3986: «The scheme and path components are required».
В документации про NSURL говорится:
> The URLs employed by the NSURL class are described in RFC 1808, RFC 1738, and RFC 2732.

и, похоже, что единственной обязательной частью является scheme
RFC3986 более актуальный документ. А особенности реализации конкретного NSURL не могут являться аргументом.
так какой хост в URL «file:///etc/passwd»?
Никакой, его здесь нет. Здесь scheme и path, согласно RFC.
и это же билдер для NSURL, поэтому, как мне кажется, особенности его реализации должны быть аргументом
Исходная фраза — ""/etc/passwd" – нормальный валидный ur".
Если бы вы сказали, что ""/etc/passwd" – нормальный валидный url для NSURL", никаких претензий бы не было.

Паттерн "Строитель" не нужен, если язык поддерживает передачу аргументов в функцию по имени и значения аргументов по-умолчанию.
Swift поддерживает и то и другое.
Паттерн билдер можно заменить на более простую функцию, без потери читаемости.


Реализация с меньшим количеством бойлерплейта
import Foundation

enum URLBuilderError: Error {
    case emptyHost
    case inconsistentCredentials
    case systemError
}

func buildUrl(
    user: String? = nil,
    password: String? = nil,
    host: String? = nil,
    port: Int? = nil,
    path: String = "",
    queryItems: [String: String]? = [String: String](),
    scheme: String = "https"
    ) throws -> URL {
    guard let host = host else {
        throw URLBuilderError.emptyHost
    }

    if user != nil {
        guard password != nil else {
            throw URLBuilderError.inconsistentCredentials
        }
    }
    if password != nil {
        guard user != nil else {
            throw URLBuilderError.inconsistentCredentials
        }
    }
    var urlComponents = URLComponents()
    urlComponents.scheme = scheme
    urlComponents.user = user
    urlComponents.password = password
    urlComponents.host = host
    urlComponents.port = port
    urlComponents.path = path
    urlComponents.queryItems = queryItems?.map {
        URLQueryItem(name: $0, value: $1)
    }

    guard let url = urlComponents.url else {
        throw URLBuilderError.systemError // Impossible?
    }
    return url
}

Фабричная функция потом может быть вызвана вот так:


_ = try buildUrl(
    user: "admin",
    password: "Qwerty", 
    host: "somehost.com",
    port: 80,
    path: "/some/path",
    queryItems: ["page": "0"])
Это понятно, конечно. Но пост не о том, как поудобней сконструировать объект URL, а о конкретном шаблоне. Так сказать, познавательный, «для самых маленьких».

P.S. Я бы назвал ваш метод makeURL() – так будет по официальному код-стайлу.

Если речь идет о шаблонах программирования, то человек явно не "самый маленький".
Можно изучить все паттерны и потом каждый день их применять. Однако смысл паттернов не в том, чтобы код написать, а чтобы добиться каких-то целей.
В случае со "Строителем" — поудобней сконструировать объект. Я сейчас помню три цели


  1. При конструировании сложного объекта, наглядно описать какое значение в какое свойство класса будет помещено.
  2. Предотвратить создание телескопических конструкторов для всех возможных инвариантов класса.
  3. Дать возможность строить объект в несколько разделенных этапов.

Вы показали только первую цель, причем неоптимально. Писать строителя для уточнения параметров нецелесообразно, если аргументы можно передавать по имени.
Иллюстрацию для второй цели вы не дали, но для ее достижения тоже нет смысла реализовывать шаблон "Строитель". Аргументам можно дать значения по-умолчанию.
Иллюстрацию для третьей цели вы тоже не дали, хотя для нее, этот шаблон реально помогает. Но такой случай очень редкий.

Спасибо за третий пункт – однозначно достойно упоминания, немного дополнил!
Обкурятся солидом своим и сидят придумывают куда бы прикостылить очередной паттерн, хипстота ей-богу.
Sign up to leave a comment.

Articles