Swift - ссылка на тип класса внутри класса - PullRequest
0 голосов
/ 06 июля 2018

При использовании статических свойств и методов типа из методов экземпляра типа я часто повторяю имя типа.

, например

class Foo
{
    // Type properties, methods

    static let kBrandColor = UIColor.red
    static let kMeaning = 42

    static func makeThing() -> Thing { ... }

    // Instance method

    func printStuff()
    {
        print("Brand Color is: \(Foo.kBrandColor)")
        print("The meaning of life is: \(Foo.kMeaning)")

        let thing = Foo.makeThing()
        print("Thing is \(thing)"
    }

    ...
}

Эти повторяющиеся ссылки на "Foo" могут (и часто делают) приводить к ошибкам при копировании, рефакторинге. Очень легко забыть изменить «Foo», и код все равно будет компилироваться.

Итак, я использовал такой шаблон:

class Foo
{
    fileprivate typealias _ThisClass = Foo

    // Type properties, methods

    static let kBrandColor = UIColor.red
    static let kMeaning = 42

    static func makeThing() -> Thing { ... }

    // Instance method

    func printStuff()
    {
        print("Brand Color is: \(_ThisClass.kBrandColor)")
        print("The meaning of life is: \(_ThisClass.kMeaning)")

        let thing = _ThisClass.makeThing()
        print("Thing is \(thing)"
    }

    ...
}

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

Есть ли лучшее, более чистое решение этой проблемы? (Я пытался выполнить поиск SO, но правильно подобрать условия поиска для такой проблемы).

Ответы [ 2 ]

0 голосов
/ 06 июля 2018

Создайте протокол наподобие Identifiable со свойством identifier. Затем приведите в соответствие любой класс, который вы хотите идентифицировать. Это протокол-ориентированный подход.

protocol Identifiable {
    static var identifier: String { get }
}
extension Identifiable {
    static var identifier: String {
        return String(describing: self)
    }
}

class X: Identifiable {}

Вам также не нужно ссылаться на имя класса. Просто позвоните type(of: instance).identifier.

0 голосов
/ 06 июля 2018

Протокол будет хорошо работать здесь. Вы можете определить свойства, требуемые протоколом, а затем применить их к любому классу, в котором вы хотите их использовать.

protocol Brandable {
    var kBrandColor: UIColor { get }
    var kMeaning: Int { get }
}

class Foo: Brandable {
    let kBrandColor: UIColor = .red
    let kMeaning: Int = 42
}

Если вы хотите повторно использовать функцию printStuff, вы также можете поместить это в протокол и добавить базовую реализацию в расширение:

protocol Brandable {
    var kBrandColor: UIColor { get }
    var kMeaning: Int { get }

    func printStuff()
}

extension Brandable {
    func printStuff() {
        print("Brand Color is: \(kBrandColor)")
        print("The meaning of life is: \(kMeaning)")
    }
}

class Foo: Brandable {
    let kBrandColor: UIColor = .red
    let kMeaning: Int = 42
}

class Bar: Brandable {
    let kBrandColor: UIColor = .blue
    let kMeaning: Int = 100
}

Foo().printStuff()
Bar().printStuff()

То же самое можно сделать с помощью функции makeStuff (). Общая функциональность идет в протоколе и его расширении. Если вам нужно изменить поведение в каком-либо классе, вам нужно только добавить собственную функцию printStuff или makeStuff, чтобы переопределить реализацию протокола по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...