使函数只能从一个类中调用

问题描述 投票:0回答:1

我具有一个类LoggingManager和一个协议LoggingHandler,并且使用单一方法send(LoggingEvent)LoggingManager保留LoggingHandler的列表。我希望LoggingManager是允许从LoggingHandler调用send(LoggingEvent)only类,并且使用该协议的类应实现send(LoggingEvent)方法。

我尝试将LoggingHandlerLoggingManager放入同一文件,并将send(LoggingEvent)标记为fileprivate。但是,在协议中是不允许的。

有没有办法使其起作用?

import Foundation

public struct LoggingEvent {
    var eventName: String
    var eventParams: [String: Any]

    public init(_ name: String, _ eventParams: [String: Any]) {
        self.eventName = name
        self.eventParams = eventParams
    }

    public init(_ name: String) {
        self.eventName = name
        eventParams = [String: Any]()
    }

    mutating public func addParameter(_ eventName: String, _ eventValue: Any) {
        self.eventParams[eventName] = eventValue
    }
}

public protocol LoggingHandler {
    func logEvent(_ event: LoggingEvent) ///<--- Only LoggingManager should call this function, but classes implementing this should override it
}

public class LoggingManager {
    private var loggingHandlers: [LoggingHandler]
    static let shared = LoggingManager()

    private init() {
        loggingHandlers = []
    }

    public func registerLoggingHandler(_ loggingHandler: LoggingHandler) {
        loggingHandlers.append(loggingHandler)
    }

    public func logEvent(_ event: LoggingEvent) {
        for handler in loggingHandlers {
            handler.logEvent(event)
        }
    }
}
swift swift-protocols
1个回答
1
投票

这不是最漂亮的解决方案,但这是一个主意。在第一个文件中,您可以定义以下类型:

struct LoggingSecurity {
    fileprivate init() {}
}

class LoggingManager {
    private let handlers: [LoggingHandler]
    private let security: LoggingSecurity

    init(handlers: [LoggingHandler]) {
        self.handlers = handlers
        self.security = .init()
    }

    func broadcast(event: LoggingEvent) {
        handlers.forEach { handler in
            handler.send(
                event: event,
                securedBy: security
            )
        }
    }
}

由于LoggingSecurity.init方法被标记为fileprivate,所以唯一可以实例化LoggingSecurity的类是LoggingManager

然后您可以在其他文件中定义以下类型:

struct LoggingEvent {
    let data: String
}

protocol LoggingHandler {
    func send(event: LoggingEvent, securedBy security: LoggingSecurity)
}

class PrintLoggingHandler: LoggingHandler {
    func send(event: LoggingEvent, securedBy security: LoggingSecurity) {
        print("LOG: \(event.data)")
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.