Все еще не уверен, что полностью понимаю, чего вы пытаетесь достичь.Вот некоторые мысли, надеюсь, они полезны.Извиняюсь, что упустил момент.
Первый вопрос: почему вы хотите, чтобы значения и состояния перечисления были изоморфными?В самом общем смысле это тиражирование информации.И реплицированная информация имеет привычку не синхронизироваться.Так что было бы полезно понять мотивацию.
Несмотря на это, вот пара возможностей.
1.Перспектива UML / Modeling
В мире UML нет реальной необходимости иметь как модель состояния, так и перечисление, связанное с ней.UML в общем не определяет, как читать значение текущего состояния объекта;однако некоторые профили (например, Исполняемый UML ) делают.В исполняемом UML любой класс, имеющий конечный автомат, автоматически получает атрибут только для чтения с именем current_state
.Возможные значения для current_state
являются названиями состояний в модели состояний.Таким образом, вы можете рассматривать его как конечный автомат, определяющий неявное перечисление.
Обратите внимание, что атрибут доступен только для чтения.Это потому, что единственный способ изменить это через конечный автомат, то есть путем отправки событий объекту.Таким образом, оно также удовлетворяет вашему второму требованию: невозможно изменить значение переменной current_state
таким образом, который нарушает протокол конечного автомата.
Даже если вы не используете исполняемый UML-профиль (илипохоже) совершенно правильно утверждать вышеизложенное как правило / соглашение.При необходимости вы можете определить свой собственный профиль, хотя это может быть излишним - зависит от ваших обстоятельств.
Ключевым моментом является то, что перечисление не требуется в мире моделирования.
2.Перспектива кода
При переводе модели в код перечисление является разумным и распространенным способом определения типа для переменной текущего состояния.В соответствии со сценарием моделирования вы бы хотели сделать атрибут current_state
доступным только для чтения из внешнего мира.Затем вам понадобятся еще три вещи:
- Реализация функций конечного автомата
- открытых членов-членов для каждого из событий, управляющих конечным автоматом
- Закрытый членфункция для обновления переменной
current_state
из реализации конечного автомата.
Таким образом, в мире кода вы предотвращаете недопустимые последовательности переменной current_state
, делая ее доступной только для чтения из внешнего мира.То есть, у вас есть только общедоступный метод чтения: нет общедоступного метода записи.
Внутри класса вы делаете приватный метод доступа закрытым и гарантируете, что единственное место, куда его вызывают, находится в реализации конечного автомата.
Вместо общедоступного средства записи вы предоставляете открытые методы, соответствующие событиям, которые управляют конечным автоматом.Более подробно о реализации конечных автоматов ниже, но вот тривиальный пример:
class Phone {
enum PhoneState {disconnected, connecting, connected, disconnecting};
public PhoneState current_state {get}; //no write accessor
//functions for generating state machine events
public void digit(int number) {..} //press digit key, e.g. while dialing
public void connect() {..} //make connection
public void disconnect() {..} //disconnect
}
Реализация конечного автомата
Существует 3 общих шаблона для реализации конечных автоматов: 1. Матрица состояний или таблица поиска 2. Вложенный переключатель 3. Шаблон состояний
Здесь представлен хороший обзор (1) здесь ;(2) и (3) покрыты здесь .
И это в основном все.Не совсем уверен, что я ответил на ваш вопрос.Если не извинения, возможно, вы могли бы быть более конкретным о том, что вы пытаетесь достичь.
hth.