デコレータ

既存の関数やクラスに機能を追加するデザインパターンで、元のコードを変更せずに拡張する

設計パターンTypeScript

デコレータとは

デコレータ (Decorator) は、既存の関数やクラスに機能を追加するデザインパターンで、元のコードを変更せずに拡張する。GoF デザインパターンの 1 つで、Python の @decorator、TypeScript の Stage 3 Decorators が言語レベルでサポートする。

関数デコレータ (高階関数)

// ログを追加するデコレータ
function withLogging<T extends (...args: any[]) => any>(fn: T): T {
  return ((...args: any[]) => {
    console.log(`Calling ${fn.name} with`, args);
    const result = fn(...args);
    console.log(`Result:`, result);
    return result;
  }) as T;
}

const add = (a: number, b: number) => a + b;
const loggedAdd = withLogging(add);
loggedAdd(1, 2); // Calling add with [1, 2] → Result: 3

TypeScript Decorators (Stage 3)

function log(target: any, context: ClassMethodDecoratorContext) {
  return function (...args: any[]) {
    console.log(`${String(context.name)} called`);
    return target.apply(this, args);
  };
}

class OrderService {
  @log
  createOrder(data: any) { /* ... */ }
}

デコレータ vs 継承

観点 デコレータ 継承
結合度 低い 高い
組み合わせ 自由に組み合わせ可能 単一継承の制約
実行時の変更 可能 不可

Python のデコレータ

import functools

def retry(max_attempts=3):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            for i in range(max_attempts):
                try:
                    return func(*args, **kwargs)
                except Exception:
                    if i == max_attempts - 1:
                        raise
        return wrapper
    return decorator

@retry(max_attempts=3)
def call_api():
    ...

実用的なデコレータ

デコレータ 用途
withLogging ログの追加
withRetry リトライの追加
withCache キャッシュの追加
withAuth 認証チェック
withValidation 入力検証

詳しくは関連書籍を参照。

関連用語