我有一个静态方法的类:这个类把调用包裹到Twitter API
在第二类中,我有一些业务逻辑.
由于封装类中某些方法的异步行为,我设计通信时遇到困难.这是我做的:
APIManager.swift
public class APIManager { class func getPermission(callback : () -> Void) { let accountStore = ACAccountStore() let accountType = ACAccountStore().accountTypeWithAccountTypeIdentifier(ACAccountTypeIdentifierTwitter) let callbackRequestAccess = { (granted: Bool,error: NSError!) -> Void in ... if(granted) { callback() } } accountStore.requestAccessToAccountsWithType(setAccountType,options: nil,completion: callbackRequestAccess) } }
Welcome.swift
public class Welcome { public func checkPermission() { APIManager.getPermission(getTweet) } public func getTweet() { ... } }
我不确定这个设计是否对.
我不想在这些类之间有很强的联系,这就是为什么我使用回调.
这是经典的设计吗?
而且,我不觉得这样的行为会很容易测试?
解决方法
您将通过不使用类方法来大大提高可测性.创建一个TwitterConnection协议.创建一个符合它的SystemTwitterConnection并通过ACAccountStore来管理事物.创建一个TestTwitterConnection,返回可配置进行测试的预设响应.您甚至可以创建一个KeychainTwitterConnection来手动管理Twitter登录,而不使用ACAccountStore,或者一些其他实现,如果苹果公司出来另一种方式来存储这些帐户.
创建时将适当的连接传递给欢迎.
如果TwitterConnection协议变大,您应该强烈地考虑将其拆分成更小的协议,例如处理较少事物的TwitterAuthenticator和TweetFetcher(即使单个类型实际上实现了所有这些协议).这可以使测试更容易,允许您的测试类型仅实现几个功能,而不是几十个.
使用闭包可能很好,但是您应该更紧密地关注Cocoa命名约定.你所说的回调通常称为完成.我也可以跟随可可的领先方法.而不是getPermission(),它将是requestAccessWithCompletionHandler().这将有助于调用者了解它与requestAccessToAccountsWithType(options:completion :)的行为非常相似.不要为呼叫者建立新的词汇表.