samedi 16 janvier 2016

How to pass data between sequential Commands?

I have a client that wants to retrieve certain data based on the combined effort of two Commands. The reason I need two Commands is that the second command relies on data from the first Command. My question is what is the best way to pass data from the first command to the second command?

I'm using a coordinating object that is a delegate of the first and second command - but this seems messy. Is this resolvable in the layer where all the Commands are housed or does it require this coordinating object?

Here's a representation of the client class:

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

The coordinator object:

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

}

Summarily, the client (ViewController) wants to fetch the schoolID given a firstName and lastName of a student. To achieve this, two Commands need to be executed - FetchStudentInfoAction and FetchSchoolInfoAction. The second Command depends on data from the first Command - in this case, FetchSchoolInfoAction needs the student's schoolName that is retrieved by the FetchStudentInfoAction.

This seems messy. If we imagine that more requests are added to ViewController, the Coordinator object will get more and more complex. Is there a better way to deal with a set of sequential Commands when the second command requires data from the first? Could this be handled by an object at the Command layer instead of with the Coordinator?

Aucun commentaire:

Enregistrer un commentaire