【问题标题】:Dealing with Closures - Make code more generic处理闭包——让代码更通用
【发布时间】:2016-01-06 16:35:22
【问题描述】:

有两个功能,如下图所示。两者的大部分功能都是相同的。它的想法是从getResponse() [Helper Callback] 中获取webservice的输出,解析并通过getResult()将信息传递给wrapper回调。

 static func getAllDealers(dealerSearchServiceDomain: ARSDealerSearchServiceDomain, wrapperCallback:(getResult: () throws -> Void) -> Void) throws
    {
        try ARSInputValidator.validateZipCode(dealerSearchServiceDomain.zip)

        try ARSDealerConnection.getAllDealers(dealerSearchServiceDomain, helperCallback: { (getResponse) -> Void in

            do
            {
                let result = try getResponse()

                try ARSDealerParser.parseDealerSearchResponse(dealerSearchServiceDomain)

                wrapperCallback(getResult: { return })
            }
            catch
            {
                wrapperCallback(getResult: { throw error })
            }
        })
    }

    static func getDealerDetails(dealerDetailsServiceDomain: ARSDealerDetailsServiceDomain, wrapperCallback:(getResult: () throws -> Void) -> Void) throws
    {
        try ARSDealerConnection.getDealerDetails(dealerDetailsServiceDomain, helperCallback: { (getResponse) -> Void in

            do
            {
                let result = try getResponse()

                try ARSDealerParser.parseDealerDetailsResponse(dealerDetailsServiceDomain)

                wrapperCallback(getResult: { return })
            }
            catch
            {
                wrapperCallback(getResult: { throw error })
            }

        })
    }

我正在尝试为常见功能添加一个单独的功能,例如,

static func parser(serviceCallDomain: ARSServiceCallDomain ,wrapperCallback:(getResult:() throws -> String) -> Void,  helperCallback:(getResponse:() throws -> String) -> Void) throws
    {
        helperCallback { (getResponse) -> Void in

但是有一个编译错误,我无法完成它。有 15 个以上的网络服务调用,所以我正在尝试显示的常见问题将非常有帮助。

下一步,我还需要将函数 parseDealerSearchResponse() 和 parseDealerDetailsResponse() 传递给通用函数。

我是闭包的新手。请帮忙。

//编辑——添加样本

我有一个解决 Git 问题的示例 - 请参阅类 Layer1.swift https://github.com/vivinjeganathan/ErrorHandling/tree/Closures-Refactor

【问题讨论】:

  • 请注意,您的“通用功能”示例不完整,请向我们展示您构建此功能的完整尝试。有点离题:还要注意Void 只是() 的类型别名(空元组type(() 也是非可选() 类型的单个值)),因此(getResult: () throws -> Void) -> Void) 等价于(getResult: () throws -> ()) -> ()) 。即使对此没有明显的约定,后者对于不在同一表达式中混合类型和该类型的类型别名是一致的。
  • ... 最后,返回 () 的函数/闭包不需要明确说明这一点,例如parser 签名中的 wrapperCallback 参数可以采用更紧凑的形式 wrapperCallback:(getResult:() throws -> String)。
  • @dfri 我已经编辑了这个问题。在 Github 中添加了一个示例项目...

标签: ios swift closures


【解决方案1】:

我认为重构代码的最好方法是定义一个函数来处理一些常见功能,如解析和验证,并最终将完成闭包调用回控制器,如下所示:

static func handleResponse(parser: Parser, validator: Validator, getResult: () throws -> AnyObject, completion: (getParsedResult: () throws -> AnyObject) -> Void)  {
    do
    {
        let result = try getResult()
        let parsedObject = try parser.parse(result)
        try validator.validate(parsedObject)
        completion(getParsedResult: { return parsedObject })
    }
    catch
    {
        completion(getParsedResult: { throw error })
    }
}

注意它接收解析器、验证器、从下层捕获结果的闭包和属于最终用户(通常是视图控制器)的完成闭包,然后这个函数可以这样使用:

static func getAllDealers(dealerSearchServiceDomain: AnyObject, wrapperCallback:(getResult: () throws -> AnyObject) -> Void) throws {
    let validator = DealersValidator() // create real validator
    let parser = DealersParser() // create real parser

    try validator.validate(dealerSearchServiceDomain)

    try ARSDealerConnection.getAllDealers(dealerSearchServiceDomain, helperCallback: { (getResponse) -> Void in
        self.handleResponse(parser, validator: validator, getResult: getResponse, completion: wrapperCallback)
    })
}

在这种情况下,handleResponse 与 getAllDealers 位于同一类,但它实际上可以是每个服务都可以调用的全局函数。

我认为使用泛型编写更好的实现是可能的,但它不会比这更短,最终你无法避免创建验证器和解析器并调用下一层。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-28
    • 1970-01-01
    • 2022-01-19
    相关资源
    最近更新 更多