我有一个客户端想要根据两个命令的共同努力来检索某些数据。我需要两个命令的原因是第二个命令依赖于第一个命令中的数据。我的问题是将数据从第一个命令传递到第二个命令的最佳方法是什么?
我正在使用一个协调对象,它是第一个和第二个命令的委托 - 但这似乎很混乱。这是否可以在所有命令所在的层中解析,或者是否需要此协调对象?
下面是客户端类的表示形式:
class ViewController: UIViewController, CoordinatorDelegate {
// ...
@IBAction func didTouchButton(sender: UIButton) {
self.coordinator.fetchSchoolID(firtName: "Jane", lastName: "Jones")
}
// MARK: - CoordinatorDelegate
func fetchSchoolIDSucceeded(ID ID: Int) {
self.updateUIWithSchoolID(ID)
}
func fetchSchoolIDFailed(error error: NSError) {
self.displayError(error)
}
}
协调器对象:
protocol CoordinatorDelegate {
func fetchSchoolIDSucceeded(ID ID: Int)
func fetchSchoolIDFailed(error error: NSError)
}
struct Coordinator: FetchSchoolInfoActionDelegate, FetchStudentInfoActionDelegate {
let actionFactory: ActionFactory
var delegate: CoordinatorDelegate?
func fetchSchoolID(firstName: String, lastName: String) {
let firstAction = self.actionFactory.fetchStudentInfoAction(firstName: firstName, lastName: lastName, delegate: self)
firstAction.execute()
}
// MARK: - FetchStudentInfoActionDelegate
func fetchStudentInfoSucceeded(studentInfo: StudentInfo) {
let secondAction = self.actionFactory.fetchShoolInfoAction(schoolName: studentInfo.schoolName, delegate: self)
secondAction.execute()
}
func fetchStudentInfoFailed(error: NSError) {
self.delegate?.fetchSchoolIDFailed(error: error)
}
// MARK: - FetchSchoolInfoActionDelegate
func fetchSchoolIDSucceeded(schoolInfo: SchoolInfo) {
self.delegate?.fetchSchoolIDSucceeded(ID: schoolInfo.ID)
}
func fetchSchoolIDFailed(error: NSError) {
self.delegate?.fetchSchoolIDFailed(error: error)
}
}
总而言之,客户(ViewController
)想要获取给定学生firstName
和lastName
的schoolID
。为此,需要执行两个命令 - FetchStudentInfoAction
和 FetchSchoolInfoAction
。第二个命令依赖于第一个命令中的数据 - 在这种情况下,FetchSchoolInfoAction
需要FetchStudentInfoAction
检索的学生schoolName
。
这似乎很混乱。如果我们想象 更多的请求被添加到 ViewController
,Coordinator
对象将变得越来越复杂。当第二个命令需要第一个命令的数据时,是否有更好的方法来处理一组顺序命令?这可以由命令层的对象而不是Coordinator
处理吗?
组合操作 (fetchSchoolID) 暗示了一个实体/关系图,该图很容易变得更加复杂。 我建议您添加一个完成处理程序模式来返回异步请求的结果。
例如,如果 execute() 函数提供了一个完成处理程序,您将能够在 fetchSchoolID 的实现中获取特定的回调。
let firstAction = self.actionFactory.fetchStudentInfoAction(firstName: firstName, lastName: lastName, delegate: self)
firstAction.execute()
{
(studentInfo) in
let secondAction = self.actionFactory.fetchShoolInfoAction( ....
secondAction.execute ...
}
这需要在操作工厂中进行轻微的设计更改(以存储和调用完成捕获,但它将大大提高组合和链接操作的灵活性。
要在操作类中实现这一点,您可以执行以下操作:
class FetchStudent:YourBaseActionClass
{
var completionHandler:((StudentInfo)->())? = nil
// execute allow specification of a completion handler
// but doesn't require it
override func execute(completion:((StudentInfo)->())? = nil)
{
completionHandler = completion
}
// I assume you have something like this in here that
// builds the StudentInfo before returning it through the delegate
func fetchComplete()
{
//... your code that prepared the student info
completionHandler?(studentInfo)
}
...