# -*- coding: utf-8 -*- #!/usr/bin/env python class StateViolationError(RuntimeError): pass class WithdrawState(object): def new_state(self, state): self.__class__ = state def confirm(self): raise NotImplementedError() def process(self): raise NotImplementedError() def revoke(self): raise NotImplementedError() def succeed(self): raise NotImplementedError() def fail(self): raise NotImplementedError() class WithdrawConfirmedState(WithdrawState): def confirm(self): raise StateViolationError('system already confirmed withdraw application') def process(self): raise self.new_state(WithdrawProcessingState) def revoke(self): raise StateViolationError('the withdraw application needs to be processed first') def succeed(self): raise StateViolationError('the withdraw application needs to be processed first') def fail(self): raise StateViolationError('the withdraw application needs to be processed first') class WithdrawProcessingState(WithdrawState): def confirm(self): raise StateViolationError('system already confirmed the withdraw application.') def process(self): raise StateViolationError('system is already processing the withdraw application') def revoke(self): self.new_state(WithdrawRevokedState) def succeed(self): self.new_state(WithdrawSucceededState) def fail(self): self.new_state(WithdrawFailedState) class WithdrawRevokedState(WithdrawState): def confirm(self): raise StateViolationError('system already confirmed the withdraw application.') def process(self): self.new_state(WithdrawProcessingState) def revoke(self): raise StateViolationError('the withdraw application has already been revoked.') def succeed(self): self.new_state(WithdrawSucceededState) def fail(self): self.new_state(WithdrawFailedState) class WithdrawSucceededState(WithdrawState): def confirm(self): raise StateViolationError('system already confirmed withdraw application.') def process(self): raise StateViolationError('system cannot process a succeeded withdraw application.') def revoke(self): raise StateViolationError('cannot withdraw a succeeded withdraw application.') def succeed(self): raise StateViolationError('the withdraw has already succeeded.') def fail(self): raise StateViolationError('cannot fail a succeeded withdraw application.') class WithdrawFailedState(WithdrawState): def confirm(self): raise StateViolationError('system already confirmed withdraw application') def process(self): raise StateViolationError('system cannot process a failed withdraw application') def revoke(self): raise StateViolationError('cannot withdraw a failed withdraw application.') def succeed(self): raise StateViolationError('cannot fail a succeeded withdraw application.') def fail(self): raise StateViolationError('the withdraw has already succeeded.') class Connection: def __init__(self): self.new_state(ClosedConnection) def new_state(self, newstate): self.__class__ = newstate def read(self): raise NotImplementedError() def write(self, data): raise NotImplementedError() def open(self): raise NotImplementedError() def close(self): raise NotImplementedError() class ClosedConnection(Connection): def read(self): raise RuntimeError('Not open') def write(self, data): raise RuntimeError('Not open') def open(self): self.new_state(OpenConnection) def close(self): raise RuntimeError('Already closed') class OpenConnection(Connection): def read(self): print 'reading' def write(self, data): print 'writing' def open(self): raise RuntimeError('Already open') def close(self): self.new_state(ClosedConnection) __all__ = ["WithdrawConfirmedState", "WithdrawProcessingState", "WithdrawRevokedState", "WithdrawSucceededState", "WithdrawFailedState", "StateViolationError"]