处理Closures - 使代码更通用 [英] Dealing with Closures - Make code more generic

查看:130
本文介绍了处理Closures - 使代码更通用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有两个功能,如下所示。大多数功能在两者中是相同的。它的想法是从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) - >无效

do
{
let result = try getResponse()

try ARSDealerParser.parseDealerSearchResponse(dealerSearchServiceDomain)

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

static func getDealerDetails(dealerDetailsS​​erviceDomain:ARSDealerDetailsS​​erviceDomain,wrapperCallback:(getResult: )throws - >空隙)→ Void)throws
{
try ARSDealerConnection.getDealerDetails(dealerDetailsS​​erviceDomain,helperCallback:{(getResponse) - > Void in

do
{
let result = try getResponse()

try ARSDealerParser.parseDealerDetailsResponse(dealerDetailsS​​erviceDomain)

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) - >无效

但有一个编译错误&我不能完成它。有15+个Web服务调用,所以一个常见的显示为我试图将是非常有益的。



下一步,我还需要传递函数parseDealerSearchResponse()& parseDealerDetailsResponse()到通用函数。



我是closures的新用户。请帮忙。



//编辑 - 添加样本



我有一个Git中的问题示例 - .swift
https://github.com/vivinjeganathan/ErrorHandling/tree/Closures -Refactor

解决方案

我认为重构代码最好的方法是定义一个函数,的常见功能,如解析和验证,最终调用完成关闭回到控制器,类似这样:

  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})
}
}

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

  static func getAllDealers(dealerSearchServiceDomain:AnyObject,wrapperCallback:(getResult: throws  - > AnyObject) - > Void)throws {
let validator = DealersValidator()//创建真正的验证器
let parser = DealersParser()//创建真正的解析器

try validator.validate(dealerSearchServiceDomain)

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

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



我认为可能使用泛型编写一个更好的实现,但它不会比这短得多,最终你不能保存自己创建验证器和解析器,并调用下一层。 / p>

There are two functions as shown below. Most of the functionality is the same in both. Its idea is to get the output of the webservice from getResponse() [Helper Callback], parse and pass the info to wrapper call back through getResult().

 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 })
            }

        })
    }

I am trying to add a separate function for the common functionality like,

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

But there is a compilation error & i am not able to complete it. There are 15+ web service calls, so a common shown as i am trying will be very helpful.

Next step, i also need to pass the functions parseDealerSearchResponse() & parseDealerDetailsResponse() to the common function.

I am new to closures. Kindly help.

//EDIT -- ADDING SAMPLE

I have a sample for the problem in Git - Refer class Layer1.swift https://github.com/vivinjeganathan/ErrorHandling/tree/Closures-Refactor

解决方案

I think the best you can do to refactor the code is to define a function that handles some of the common functionality like parsing and validation and that ultimately calls the completion closure back to the controller, something like this:

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 })
    }
}

notice that it receives the parser, validator, the closure that captures the result from the layer below and the completion closure that belongs to the final user (usually the View Controller), and then this function could be used like this:

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)
    })
}

in this case handleResponse lives in the same class with getAllDealers but it can actually be a global function that every service can call.

I think that it might be possible to write a better implementation using generics but it wouldn't be much shorter than this, in the end you can't save yourself from creating the validators and parsers and call the next layer.

这篇关于处理Closures - 使代码更通用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆