はじめに
フロントエンドのコードをもっときれいに書きたいという思いから、デザインパターンについて学んでみることにしました。
今回はDecoratorについてまとめました。
Decorator
Decoratorは継承を使わずに既存のクラスを拡張するための、構造に関するデザインパターンの一つです。
継承と同様に、SOLIDの単一責任の原則やオープン・クローズドの原則に違反しない形で機能拡張を行えるようになります。
Decoratorのコンストラクタ引数で既存オブジェクトを読込み、メンバとして設定するような形で実現します。
継承はコンパイル時、Decoratorはプログラムの実行時が機能拡張のタイミングとなります。
実装例
以下のCircle
クラスに、Decoratorで色に関する情報(color)を加えることを考えます。
class Shape {}
class Circle extends Shape
{
constructor(radius=0)
{
super();
this.radius = radius;
}
resize(factor)
{
this.radius *= factor;
}
toString()
{
return `A circle of radius ${this.radius}`;
}
}
DecoratorとしてColoredShape
クラスを用意し、コンストラクタの引数としてColor
クラスのインスタンスをラッピングします。
class ColoredShape extends Shape
{
constructor(shape, color)
{
super();
this.shape = shape;
this.color = color;
}
toString()
{
return `${this.shape.toString()} ` +
`has the color ${this.color}`;
}
}
circle
インスタンス、redCircle
インスタンスをそれぞれつくってtoString()
を出力すると、確かに以下のような結果となります。
let circle = new Circle(2);
console.log(circle.toString());
let redCircle = new ColoredShape(circle, 'red');
console.log(redCircle.toString());
A circle of radius 2
A circle of radius 2 has the color red