I have an Order class that goes through a series of defined states. To help with this, I applied the State pattern so that the Order object has a CurrentState member that implements the IOrderState interface. Then I have specific implementations of this interface, such as OrderStateNew, OrderStateDelivered, etc. Etc.
My question is: what is the correct way to transition an Order object between states? Is it permissible to have an Order.SetState () method that allows an external service to set state? The criteria that determine state changes are stored externally on the Order object, so this seems like the obvious answer, but I'm a little awkward that the public method on my object changes something as fundamental as this.
Additional clarification I thought it would be useful to add more detailed information about my implementation, because I am wondering if I use the template correctly in the first place. Here is the pub API for creating and authorizing an order
Dim orderFacade As New OrderFacade Dim order = orderFacade.createFrom(customer) ' Add lines etc ' This will validate the order and transition it to status 'Authorised' Dim valid = orderFacade.Authorise(order) ' This will commit the order, but only if it is at status 'Authorised' Dim result = orderFacade.Commit()
The OrderFacade.Authorise () function looks something like this:
Public Function Authorise(ByRef originalOrder As Order) As ValidationSummary If originalOrder.CurrentState.CanAuthorise() Then Dim validator = OrderValidatorFactory.createFrom(originalOrder) Dim valid = validator.ValidateOrder(originalOrder) If valid.IsValid Then originalOrder.SetOrderStatus(OrderStatus.Authorised) End If Return valid End If End Function
As you can see, the CurrentState member is the current implementation of IOrderState, which determines which actions are valid for the object. I am wondering if this should be responsible for defining the transition, and not in OrderFacade?
James source share