r/programming - It's OK to hardcode feature flags
フィーチャーフラグについてメモ
はじめに
フィーチャーフラグとは、アプリケーションの特定の機能をオン/オフできる仕組みのことです。新機能のリリース管理、A/Bテスト、段階的なロールアウトなどに使用されます。
フィーチャーフラグ実装の基本原則
- シンプルに始める
- 必要な機能だけを実装する
- 技術的負債を管理する
実装パターン
1. ハードコードされたフラグ(最もシンプル)
最も基本的な実装方法です。小規模なプロジェクトや、頻繁な変更が必要ない機能に適しています。
class FeatureFlags {
  private static readonly flags = {
    NEW_UI: false,
    BETA_FEATURE: false,
    EXPERIMENTAL_API: false
  };
  static isEnabled(flag: keyof typeof FeatureFlags.flags): boolean {
    return this.flags[flag];
  }
}
// 使用例
if (FeatureFlags.isEnabled('NEW_UI')) {
  // 新UIを表示
} else {
  // 従来のUIを表示
}
このパターンのメリット:
- 実装が極めてシンプル
- コードレビューで変更が明確
- デプロイメントプロセスと完全に統合
- パフォーマンスオーバーヘッドなし
2. 設定ファイルベースのフラグ(中程度の柔軟性)
設定ファイルを使用することで、コードの再デプロイなしでフラグを変更できます。
// config/feature-flags.json
{
  "feature_flags": {
    "NEW_UI": {
      "enabled": false,
      "description": "新しいUIデザインの有効化",
      "owner": "UIチーム"
    },
    "BETA_FEATURE": {
      "enabled": true,
      "description": "ベータ機能",
      "owner": "製品チーム"
    }
  }
}
// FeatureFlags.ts
class FeatureFlags {
  private static config: any = null;
  static async initialize() {
    const response = await fetch('/config/feature-flags.json');
    this.config = await response.json();
  }
  static isEnabled(flag: string): boolean {
    return this.config?.feature_flags[flag]?.enabled ?? false;
  }
}
このパターンのメリット:
- 設定変更が容易
- フラグに関するメタデータの管理が可能
- 環境ごとに異なる設定が可能
3. データベースベースのフラグ(最も柔軟)
大規模なアプリケーションや、動的な制御が必要な場合に適しています。
interface FeatureFlag {
  id: string;
  name: string;
  enabled: boolean;
  description: string;
  rules: {
    type: 'percentage' | 'group' | 'region';
    value: any;
  }[];
  userPercentage: number;
  lastModified: Date;
}
このパターンのメリット:
- リアルタイムな制御が可能
- ユーザーごとの制御が可能 → 段階的なロールアウトのサポート
- 管理用UIの実装が可能
どの実装を選ぶべきか?
以下の質問に答えることで、適切な実装パターンを選択できます:
- 
フラグの変更頻度はどの程度か? - 低頻度 → ハードコード
- 中頻度 → 設定ファイル
- 高頻度 → データベース
 
- 
誰がフラグを管理するのか? - 開発者のみ → ハードコード
- 開発者とオペレーション → 設定ファイル
- プロダクトマネージャーも含む → データベース(+ 管理UI)
 
- 
段階的ロールアウトは必要か? - 不要 → ハードコードまたは設定ファイル
- 必要 → データベース
 
実装時の注意点
- 
フラグの寿命を管理する - 一時的なフラグは明確な削除計画を立てる
- コメントで目的と予定を記録する
 
- 
パフォーマンスを考慮する - フラグの評価は頻繁に行われる可能性があるため、キャッシュを検討
- データベースアクセスは最小限に抑える
 
- 
デフォルト値を適切に設定する - フラグが見つからない場合のフォールバック動作を明確にする
- 安全側にデフォルトを設定する
 
- 
監視とログ記録 - フラグの状態変更をログに記録
- 問題が発生した際の切り戻しプランを用意
 
まとめ
フィーチャーフラグの実装は、プロジェクトの規模や要件に応じて適切なアプローチを選択することが重要です。必要以上に複雑な実装を避け、シンプルさを保ちながら、必要な機能を段階的に追加していくことをお勧めします。
