Быстрое наследование одноэлементного паттерна?

Имейте этот класс, который никогда не используется непосредственно, только унаследованный:

class ApiBase {}

Как определить общий статический синглтон default Вот? - Так что я могу:

class FooApi: ApiBase {}  // Want only one instance of `FooApi`
class BarApi: ApiBase {}  // Want only one instance of `BarApi`

FooApi.default.foo_api_only_method_name()
BarApi.default.bar_api_only_method_name()

Единственное, о чем я могу думать, это создать protocol который FooApi а также BarApi нужно реализовать. Но это кажется неоптимальным, я бы предпочел написать такую ​​реализацию:

func `default`<T: ApiBase>() -> T {
    if staticInstance == nil {
        staticInstance = T()
    }
    return staticInstance
}

2 ответа

Решение

Закончилось добавление интерфейса:

protocol Instance {
    associatedtype T
    // static var _instance: T {get set}  # Can't use; can't override :(
    static func instance() -> T
}

Можно использовать так:

class ApiBase: Instance {
    var root: String = ""

    static var _instance: ApiBase = ApiBase()

    open class func instance() -> ApiBase {
        if _instance.root == "" {
            _instance = ApiBase()
        }
        return _instance
    }
}

Наследование:

class FooApi: ApiBase {
    static var _fooApi: FooApi = FooApi()

    override class func instance() -> FooApi {
        if _fooApi.root == "" {
            _fooApi = FooApi()
        }
        return _instance
    }
}

Это неоптимально, так как тело instance функции идентичны по шаблону. Но это работает.

Я не смог найти способ решить эту проблему с помощью дженериков, но я бы предложил

static let `default` = FooApi()

а также

static let `default` = BarApi()

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

Другие вопросы по тегам