Day 3: インターフェース - 課題

チャレンジ1: プラグインシステム

プラグイン可能なロギングシステムを実装してください。

要件

  • Loggerインターフェースを定義
- Info(message string) - Error(message string) - Debug(message string)
  • ConsoleLoggerを実装(標準出力)
  • TimestampLoggerを実装(タイムスタンプ付きデコレータ)
  • App構造体でLoggerを使用

期待される出力例

[APP][INFO] [15:04:05] アプリケーション起動
[APP][DEBUG] [15:04:05] デバッグ情報
[APP][ERROR] [15:04:05] エラーが発生

---

チャレンジ2: データストアの抽象化

複数のストレージバックエンド(メモリ、ファイル)をサポートするKVストアを実装してください。

要件

  • KVStoreインターフェースを定義
- Get(key string) (string, error) - Set(key string, value string) error - Delete(key string) error - List() []string
  • MemoryStoreを実装
  • CachedStoreを実装(キャッシュレイヤー)
  • スレッドセーフに実装する(sync.RWMutex使用)

テストコード

func main() {
    // メモリストア
    memory := NewMemoryStore()
    memory.Set("name", "太郎")
    value, _ := memory.Get("name")
    fmt.Println("Memory:", value)  // Memory: 太郎

    // キャッシュ付きストア
    cache := NewMemoryStore()
    source := NewMemoryStore()
    source.Set("age", "25")

    cached := NewCachedStore(cache, source)
    age, _ := cached.Get("age")  // ソースから取得
    fmt.Println("First get:", age)

    age, _ = cached.Get("age")   // キャッシュから取得
    fmt.Println("Second get:", age)
}

---

チャレンジ3: 型アサーションの活用

JSONデータを処理する汎用関数を実装してください。

要件

  • ProcessJSON関数を実装
- map[string]interface{}を受け取る - 値の型に応じて異なる処理を行う - 型スイッチを使用する
  • サポートする型:
- string: そのまま出力 - float64: 小数点以下2桁で出力 - bool: "Yes"/"No"に変換 - []interface{}: カンマ区切りで出力 - map[string]interface{}: 再帰的に処理

テストデータ

data := map[string]interface{}{
    "name":   "太郎",
    "age":    25.0,
    "active": true,
    "tags":   []interface{}{"go", "rust", "typescript"},
    "address": map[string]interface{}{
        "city":    "東京",
        "zipcode": "100-0001",
    },
}

---

チャレンジ4: デザインパターンの実装

Strategyパターンを使った計算機を実装してください。

要件

  • Operationインターフェースを定義
- Execute(a, b float64) float64 - Name() string
  • 以下の演算を実装
- Add(加算) - Subtract(減算) - Multiply(乗算) - Divide(除算)
  • Calculator構造体を実装
- SetOperation(op Operation) - Calculate(a, b float64) float64

---

提出について

  • 各チャレンジを別々のファイルとして作成してください
  • インターフェースに対してドキュメントコメントを記述してください
  • テスト可能なコードを心がけてください