У меня есть класс Order, который проходит через серию определенных состояний. Чтобы помочь в этом, я реализовал шаблон State так, что у объекта Order есть член CurrentState, который реализует интерфейс IOrderState. Затем у меня есть конкретные реализации этого интерфейса, такие как OrderStateNew, OrderStateDelivered и т. Д. И т. Д.
Мой вопрос: как правильно перевести объект Order между состояниями? Допустимо ли иметь метод Order.SetState (), который позволяет внешней службе устанавливать состояние? Критерии, которые определяют изменения состояния, хранятся внешне в объекте Order, поэтому это кажется очевидным ответом, но мне немного неловко иметь открытый метод для изменения чего-то столь фундаментального, как этот.
Дополнительные уточнения
Я подумал, что было бы полезно добавить некоторые подробности о моей реализации, потому что мне интересно, правильно ли я использую шаблон в первую очередь. Вот пульсирующий API для создания и авторизации заказа
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()
Функция OrderFacade.Authorise () выглядит примерно так
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
Как видите, элемент CurrentState является текущей реализацией IOrderState, которая определяет, какие действия допустимы для объекта. Интересно, должно ли это отвечать за определение перехода, а не за OrderFacade?