Decorator パターン実装
既存オブジェクトの振る舞いを動的に拡張し、継承を使わずに機能を追加するデザインパターン
設計パターンTypeScript
Decorator パターンとは
Decorator パターンは、既存のオブジェクトをラップして振る舞いを動的に追加する GoF デザインパターンである。継承ではなくコンポジションで機能を拡張するため、機能の組み合わせが自由で、組み合わせの爆発を避けられる。
基本的な実装
interface Logger {
log(message: string): void;
}
class ConsoleLogger implements Logger {
log(message: string) { console.log(message); }
}
// Decorator: タイムスタンプを追加
class TimestampLogger implements Logger {
constructor(private inner: Logger) {}
log(message: string) {
this.inner.log(`[${new Date().toISOString()}] ${message}`);
}
}
// Decorator: ログレベルを追加
class LevelLogger implements Logger {
constructor(private inner: Logger, private level: string) {}
log(message: string) {
this.inner.log(`[${this.level}] ${message}`);
}
}
// 組み合わせて使う (順序を変えると出力が変わる)
const logger = new TimestampLogger(new LevelLogger(new ConsoleLogger(), 'INFO'));
logger.log('Server started');
// → [2026-03-22T10:00:00.000Z] [INFO] Server started
Decorator は同じインターフェースを実装し、内部に別の実装を持つ。これにより、任意の順序で任意の数の Decorator を重ねられる。
継承との比較
// ❌ 継承: 組み合わせが爆発する
class TimestampConsoleLogger extends ConsoleLogger { /* ... */ }
class LevelConsoleLogger extends ConsoleLogger { /* ... */ }
class TimestampLevelConsoleLogger extends ConsoleLogger { /* ... */ }
class TimestampFileLogger extends FileLogger { /* ... */ }
// → 機能 N 個 × ロガー M 種 = N×M クラスが必要
// ✅ Decorator: 自由に組み合わせ
const logger = new TimestampLogger(new LevelLogger(new FileLogger()));
// → 機能 N 個 + ロガー M 種 = N+M クラスで済む
関数ベースの Decorator
TypeScript/JavaScript では、クラスを使わず高階関数で Decorator を実装する方が簡潔な場合が多い。
TypeScript 5.0 の Decorator 構文
TypeScript 5.0 で TC39 Stage 3 の Decorator 構文が導入された。
function log(target: any, context: ClassMethodDecoratorContext) {
return function (this: any, ...args: any[]) {
console.log(`${String(context.name)} called with`, args);
const result = target.apply(this, args);
console.log(`${String(context.name)} returned`, result);
return result;
};
}
class OrderService {
@log
calculateTotal(items: Item[]): number {
return items.reduce((sum, item) => sum + item.price, 0);
}
}
実務での応用
| 場面 | Decorator の例 |
|---|---|
| Express ミドルウェア | 認証、ログ、CORS、レート制限 |
| AWS SDK ミドルウェア | リトライ、ログ、メトリクス |
| Lambda ハンドラー | エラーハンドリング、認証、バリデーション |
| React HOC | 認証ガード、ローディング表示 |
全体像を把握するには関連書籍も有用。