У цьому випадку я б сказав, що ідеальна відповідь полягає в тому, що це залежить від того, як споживаються перерахунки, але що в більшості випадків, мабуть, найкраще визначити всі переліки окремо, але якщо будь-який з них уже пов'язаний дизайном, ви повинні надати засоби введення зазначених сполучень перераховують колективно. Насправді у вас є толерантність зчеплення до кількості вже наявної навмисної зв'язку, але не більше.
Враховуючи це, найбільш гнучким рішенням, ймовірно, є визначення кожного перерахунку в окремому файлі, але надавати зв'язані пакети, коли це розумно робити (як це визначено за призначенням включених переліків).
Визначення всіх ваших перерахувань в одних і тих же файлів пар їх разом, і висуненням викликає який - або код , який залежить від одного або декількох перерахувань залежить від всіх перерахувань, незалежно від того, є чи на самому справі код використовує будь-які інші перерахувань.
#include "enumList.h"
// Draw map texture. Requires map_t.
// Not responsible for rendering entities, so doesn't require other enums.
// Introduces two unnecessary couplings.
void renderMap(map_t, mapIndex);
renderMap()
Швидше за все, тільки про це знають map_t
, тому що в іншому випадку будь-які зміни інших впливатимуть на них, навіть якщо вони насправді не взаємодіють з іншими.
#include "mapEnum.h" // Theoretical file defining map_t.
void renderMap(map_t, mapIndex);
Однак у випадку, коли компоненти вже з'єднані між собою, надання декількох перерахунків у одному пакеті може легко забезпечити додаткову ясність та простоту, за умови наявності чіткої логічної причини для перерахунків, що використання цих переліків також пов'язане, а надання їх також не вводить додаткових муфт.
#include "entityEnum.h" // Theoretical file defining entity_t.
#include "materialsEnum.h" // Theoretical file defining materials_t.
// Can entity break the specified material?
bool canBreakMaterial(entity_t, materials_t);
У цьому випадку немає прямого логічного зв’язку між типом сутності та типом матеріалу (якщо припустимо, що сутності не створені з одного із визначених матеріалів). Якщо ж у нас був випадок, коли, наприклад, один перерахунок явно залежить від іншого, то має сенс надати єдиний пакет, що містить усі зв'язані перерахунки (як і будь-які інші зв'язані компоненти), щоб з'єднання могло бути Ізольована до цього пакету настільки, наскільки це розумно можливо.
// File: "actionEnums.h"
enum action_t { ATTACK, DEFEND, SKILL, ITEM }; // Action type.
enum skill_t { DAMAGE, HEAL, BUFF, DEBUFF, INFLICT, NONE }; // Skill subtype.
// -----
#include "actionTypes.h" // Provides action_t & skill_t from "actionEnums.h", and class Action (which couples them).
#include "entityEnum.h" // Theoretical file defining entity_t.
// Assume ActFlags is or acts as a table of flags indicating what is and isn't allowable, based on entity_t and Action.
ImplementationDetail ActFlags;
// Indicate whether a given type of entity can perform the specified action type.
// Assume class Action provides members type() and subtype(), corresponding to action_t and skill_t respectively.
// Is only slightly aware of the coupling; knows type() and subtype() are coupled, but not how or why they're coupled.
bool canAct(entity_t e, const Action& act) {
return ActFlags[e][act.type()][act.subtype()];
}
Але на жаль ... навіть коли два перерахунки поєднані між собою, навіть якщо це щось таке сильне, як "другий перелік забезпечує підкатегорії для перших перерахунків", все одно може настати час, коли потрібен лише один із переліків.
#include "actionEnums.h"
// Indicates whether a skill can be used from the menu screen, based on the skill's type.
// Isn't concerned with other action types, thus doesn't need to be coupled to them.
bool skillUsableOnMenu(skill_t);
// -----
// Or...
// -----
#include "actionEnums.h"
#include "gameModeEnum.h" // Defines enum gameMode_t, which includes MENU, CUTSCENE, FIELD, and BATTLE.
// Used to grey out blocked actions types, and render them unselectable.
// All actions are blocked in cutscene, or allowed in battle/on field.
// Skill and item usage is allowed in menu. Individual skills will be checked on attempted use.
// Isn't concerned with specific types of skills, only with broad categories.
bool actionBlockedByGameMode(gameMode_t mode, action_t act) {
if (mode == CUTSCENE) { return true; }
if (mode == MENU) { return (act == SKILL || act == ITEM); }
//assert(mode == BATTLE || mode == FIELD);
return false;
}
Тому, оскільки ми знаємо і те, що завжди може бути ситуація, коли визначення декількох перерахувань у одному файлі може додати непотрібне з'єднання, а надання сполучених перерахунків в одному пакеті може уточнити використання та дозволить нам виділити власне код з'єднання як Наскільки це можливо, ідеальним рішенням є визначення кожного перерахування окремо та надання спільних пакетів для будь-яких перерахунків, які мають бути часто використані разом. Єдиними перерахунками, визначеними в тому самому файлі, будуть ті, які нерозривно пов'язані між собою, таким чином, що для використання одного необхідне використання іншого.
// File: "materialsEnum.h"
enum materials_t { WOOD, STONE, ETC };
// -----
// File: "entityEnum.h"
enum entity_t { PLAYER, MONSTER };
// -----
// File: "mapEnum.h"
enum map_t { 2D, 3D };
// -----
// File: "actionTypesEnum.h"
enum action_t { ATTACK, DEFEND, SKILL, ITEM };
// -----
// File: "skillTypesEnum.h"
enum skill_t { DAMAGE, HEAL, BUFF, DEBUFF, INFLICT, NONE };
// -----
// File: "actionEnums.h"
#include "actionTypesEnum.h"
#include "skillTypesEnum.h"