我有一个静态方法的类:这个类包装了对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() {
...
}
}
我不确定这个设计是否合适。 我不想在这些类之间建立强大的联系,这就是我使用回调的原因。
这是经典设计吗? 而且,我觉得这种行为不容易测试吗?
答案 0 :(得分:7)
通过不使用类方法,您将大大提高可测试性。创建TwitterConnection
协议。创建符合它的SystemTwitterConnection
并通过ACAccountStore
管理事物。创建一个TestTwitterConnection
,返回您可以配置用于测试的预设响应。您甚至可以创建KeychainTwitterConnection
来手动管理Twitter登录而不使用ACAccountStore
,或者如果Apple推出另一种存储这些帐户的方法,则可以创建其他实现。
创建时将适当的连接传递给Welcome
。
如果TwitterConnection
协议变大,您应该强烈考虑将其拆分为较小的协议,例如处理较少事情的TwitterAuthenticator
和TweetFetcher
(即使单个类型实际实现所有这些协议)。通过允许您的测试类型仅实现几个函数而不是几十个函数,这可以使测试变得更加容易。
闭包的使用可能很好,但你应该更贴近Cocoa命名约定。您所谓的callback
传统上称为completion
。我还会关注Cocoa在如何命名方法方面的领先优势。它不是getPermission()
,而是requestAccessWithCompletionHandler()
。这将有助于调用者理解它与requestAccessToAccountsWithType(options:completion:)
具有非常相似的行为。不要为调用者构建新的词汇表。
答案 1 :(得分:1)
https://en.wikipedia.org/wiki/Observer_pattern
它将帮助您解耦事件发布者(Observable)和消费者(Observer)
你也可以有一个特殊的Observable实现
它不会连接到任何地方,而是通过静态内容通知观察者
所以你直接调用notifyObservers
方法来测试Observers的行为。