В данной заметке мы не будем рассматривать enum с технической стороны, нас будет интересовать, когда же стоит применять их c точки зрения проектирования.
Enum — это очень дешевый и удобный инструмент, который позволяет отнести сущность к той или иной категории. Один из самых частых примеров — это состояние заказа { OnDelivery, Delivered, Completed, Canceled }.
Если список доступных категорий не изменяется или изменяется очень редко, то можно спокойно использовать enum. Вся его прелесть заключается в возможности написать if (order.State == OrderState.Canceled), т.е. в возможности легко прикрутить поведение к конкретной категории.
Когда же список категорий должен быть динамическим, т.е. должна быть возможность добавлять новые категории и изменять старые, то enum использовать просто не получится. Ну например, нужен список тегов, которыми можно помечать заказ, и хочется, чтобы этот список заполняли пользователи. В таком случае создается справочник (CRUD) с сущностью тега, что само по себе требует дополнительное время. Проблемы возникают тогда, когда к определенному тегу нужно прикрутить поведение. Допустим нужно при получении отрицательного отзыва пометить заказ тегом «Проблемный заказ». Тогда необходимо в сущность добавлять дополнительное поле с признаком, который будет отвечать за это поведение. В простейшем случае это свойство «IsBadReviewMarker» типа boolean.
var orderTags = tags.where(t => t.IsBadReviewMarker);
setOrderTags(orderTags);
Пример, как это выглядело бы с enum:
setOrderTags([Tag.ProblemOrder]);
Таким образом главным вопросом, на который нужно ответить, чтобы сделать выбор, является «как часто меняется список категорий».