The CardReader object can now be refactored into a much simpler object, which is only responsible for the run loop:
class CardReader {
internal var state: CardReaderState = UnknownState()
func start() {
while true {
print("\(state)")
perform()
sleep(1)
}
}
func perform() {
state.perform(context: self)
}
}
Running CardReader is the same as previously.
Note that we also implemented the perform() method. As CardReader is the context, we can advance each step manually by calling perform().
As you can see, our context object is much simpler. As each state has access to the context, it is also possible to extend capabilities directly within the context, if those capabilities need to be available for every state.
Another interesting feature to note is that with Swift, state objects and their conformance to CardReaderState can be decoupled through protocol extensions. You can imagine complex objects being given their state machine capabilities through extensions.