首先,我认为没有必要像您那样堆叠层,例如,通过将验证功能添加为层,您正在增加耦合,使该层依赖于下面的层(解析、网络等),相反,为什么不单独验证以使其仅依赖于数据?:
class ViewController: UIViewController {
var validator = InputValidator()
override func viewDidLoad() {
super.viewDidLoad()
do {
try validator.validateInput("INPUT")
try Fetcher.requestDataWithParams("INPUT")
}
catch {
handleError(error)
}
}
}
现在验证功能不依赖于其他层,因此通信流程如下:
视图控制器 ParsingLayer NetworkingLayer
我确实重命名了图层,但不一定非要这样,您可以添加或删除图层。
如果我尝试解释我的方法,我认为会有点复杂,所以我将使用前面的层给出一个示例,首先是底层:
class NetworkingLayer {
class func requestData(params: AnyObject, completion: (getResult: () throw -> AnyObject) -> Void) -> Void {
session.dataTaskWithURL(url) { (data, urlResponse, var error) in
if let error = error {
completion(getResult: { throw error })
} else {
completion(getResult: { return data })
}
}
}
}
我省略了一些代码部分,但我的想法是执行任何必要的步骤以使层工作(创建会话等)并始终通过完成闭包进行通信;顶部的图层如下所示:
class ParsingLayer {
class func requestObject(params: AnyObject, completion: (getObject: () throw -> CustomObject) -> Void) -> Void {
NetworkingLayer.requestData(params, completion: { (getResult) -> Void in
do {
let data = try getResult()
let object = try self.parseData(data)
completion(getObject: { return object })
}
catch {
completion(getObject: { throw error })
}
})
}
}
注意完成闭包是不一样的,因为每一层都增加了功能,返回的对象可能会改变,还要注意do语句中的代码可能会以两种方式失败,首先是网络调用失败,然后是如果无法解析来自网络层的数据;同样,与顶层层的通信始终通过完成闭包完成。
最后,ViewController 可以使用 Parsing 层在这种情况下所期望的闭包调用下一层,并且能够处理源自任何层的错误:
override func viewDidLoad() {
super.viewDidLoad()
do {
try validator.validateInput("INPUT")
try ParsingLayer.requestObject("INPUT", completion: { (getObject) in
do {
let object = try getObject()
try self.validator.validateOutput(object)
print(object)
}
catch {
self.handleError(error)
}
})
catch {
handleError(error)
}
}
请注意,在完成闭包中有一个do catch,这是必要的,因为调用是异步进行的,现在响应已经通过所有层并且实际上已经更改为更专业的类型,你甚至可以无需为验证功能制作层即可验证结果。
希望对你有帮助。