0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

command pattern

Last updated at Posted at 2019-05-20

command pattern

callbackを登録するようなもの
オペレーションの呼び出しと実行を分離する

example

commandはreceiverに移譲するだけのものから、それ自身が処理をするものまである。

protocol CommandProtocol {
    func exec() {}
}

class PrintCommand: CommandProtocol {
    private let receiver: receiver

    func exec() { receiver.print() }
}

class Receiver {
    func print() {
        print(nextLine)
    }
}


class Invoker {
    private let command: CommandProtocol

    init(command: CommandProtocol) {
        self.command = command
    }

    func acceptInput() {
        command.exec()
    }
}

swift の BackgroundTask は適当な時間で強制終了される。
commandパターンによりretryをサポートする。

final class BackgroundCommand {
    enum Status {
        case willBegin, doing, done, failed
    }

    private let receiver: Receiver
    private let input: ReceiverInput
    private var status: Status = .willBegin
    private var backgroundTaskID: UIBackgroundTaskIdentifier = .invalid

    init(receiver: Receiver, input: ReceiverInput) {
        self.receiver = receiver
        self.input = input
    }

    func exec() {
        status = .doing

        backgroundTaskID = UIApplication.shared.beginBackgroundTask(withName: "TASK_NAME", expirationHandler: { [weak self] in self.status = .failed })

        DispatchQueue.global(qos: .userInitiated).async { [weak self] in
            guard
                let r = receiver,
                let i = input,
                let taskID = backgroundTaskID else {
                self?.status = .failed
                return
            }

            r.action(i)

            UIApplication.shared.endBackgroundTask(taskID)
            self?.backgroundTaskID = .invalid
            self?.status = .done
        }
    }

    func retry() {
        guard status == .doing else { fatalError() } // 適当に処理

        receiver.restore() // receiverの内部状態が変わるとき
        status = .willBegin
        exec()
    }
}
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?