Decoratorパターンとは、既存のクラスに機能を追加する際に、サブクラスを使わずに追加機能を付け加えるデザインパターンだ。これにより、クラスの元の機能をそのまま保ちながら、新しい機能を柔軟に追加できる。
たとえば、キャラクターの攻撃力に「炎の力」や「氷の力」を後から追加するような場面で、このパターンが使える。
では、サンプルコードを一緒に見ていこう。
まずは、基本的なオブジェクトを作ろう。ここでは、単純な「ケーキ」を表すクラスを作成する。このケーキには、価格を表示するためのメソッド
getPrice() があるだけだ。
// 基本のケーキクラス
class Cake {
getPrice() {
return 500; // ケーキの基本価格
}
}
次に、ケーキに新しい機能(デコレーション)を追加するためのデコレータークラスを作成しよう。このデコレーターは、元のケーキに飾り付けを加え、その結果価格が上がる仕組みだ。
// デコレーターの基礎クラス
class CakeDecorator {
constructor(cake) {
this.cake = cake; // 元のケーキ
}
getPrice() {
return this.cake.getPrice(); // 元のケーキの価格を返す
}
}
では、具体的なデコレーションを追加しよう。例えば、チョコレートのトッピングやフルーツのトッピングを作成し、それぞれケーキの価格を増加させるようにしてみる。
// チョコレートデコレーター
class ChocolateDecorator extends CakeDecorator {
getPrice() {
return this.cake.getPrice() + 200; // チョコレートで価格を増加
}
}
// フルーツデコレーター
class FruitDecorator extends CakeDecorator {
getPrice() {
return this.cake.getPrice() + 300; // フルーツで価格を増加
}
}
最後に、デコレーターを使って元のケーキに飾りを追加し、最終的な価格を表示しよう。デコレーターを複数適用することも可能で、それぞれの飾りで価格が変わる様子を確認してみよう。
// 基本のケーキを作成
const simpleCake = new Cake();
console.log("シンプルケーキの価格: ¥" + simpleCake.getPrice()); // ¥500
// チョコレートで飾る
const chocolateCake = new ChocolateDecorator(simpleCake);
console.log("チョコレートケーキの価格: ¥" + chocolateCake.getPrice()); // ¥700
// さらにフルーツで飾る
const deluxeCake = new FruitDecorator(chocolateCake);
console.log("デラックスケーキの価格: ¥" + deluxeCake.getPrice()); // ¥1000
これでDecoratorパターンの解説は終わりだ。
このパターンを使うと、元のクラスを修正せずに追加機能を柔軟に取り入れられるため、機能拡張が簡単になる。